Отобразить два класса в одну таблицу - PullRequest
0 голосов
/ 17 января 2019

В устаревшей БД есть таблица NODES с дюжиной «маленьких» столбцов и столбцом больших объектов. Класс NodeEntity сопоставлен с таблицей NODES.

В целях повышения производительности я не хочу загружать столбец больших объектов каждый раз, когда получаю доступ к БД. Я знаю два подхода для достижения этой цели:

  • Ленивые загруженные свойства
  • Отдельный класс сущностей (идея взята из здесь )

Свойства с отложенной загрузкой хороши, когда вы загружаете данные только из БД. Но если вам нужно сохранить сущности, существует риск потери ваших данных, если вы забудете забрать загруженные ленивые свойства заранее.

Поэтому я выбрал второй подход.

Я создал отдельный небольшой класс NodeEntityLite со свойствами, сопоставленными со столбцами без больших объектов таблицы NODES. Я изменил класс NodeEntity, чтобы он наследовал от класса NodeEntityLite. Я изменил сопоставления для моих классов и использовал подкласс union для наследования.

public class NodeEntityLite {
  public virtual long Id { get; set; }
  public virtual string Code { get; set; }
}
public class NodeEntity : NodeEntityLite {
  public virtual string NOTE { get; set; } // type:clob
}

Отображение FluentNHibernate для класса NodeEntityLite равно

public void Override(AutoMapping<NodeEntityLite> mapping) {
    mapping.Table("NODES");
    mapping.UseUnionSubclassForInheritanceMapping();
}

Отображение FluentNHibernate для класса NodeEntity:

public void Override(AutoMapping<NodeEntity> mapping) {
    mapping.Table("NODES");
    mapping.Map(e => e.NOTE).CustomType("StringClob").CustomSqlType("NCLOB");
}

Я ожидал, что при выполнении select n from NodeEntityLite n where n.Id = :p0 HQL NHibernate генерирует команды SQL без столбца NOTE:

select nodeentity0_.ID as id1_87_, 
       nodeentity0_.CODE as code2_87_
    from from NODES nodeentity0_ 
    where nodeentity0_.ID=:p0;

Но NHibernate генерирует совершенно другую команду SQL (столбец NOTE не пропущен, как я ожидал):

select nodeentity0_.ID as id1_87_, 
       nodeentity0_.CODE as code2_87_, 
       nodeentity0_.NOTE as note14_87_, 
       nodeentity0_.clazz_ as clazz_ 
    from ( select ID, CODE, NOTE, 1 as clazz_ from NODES ) nodeentity0_ 
    where nodeentity0_.ID=:p0;

Я пытался изменить наследование и использовать другие отображения, но безуспешно.

Вопрос в следующем: Можно ли сопоставить несколько классов одной и той же таблице в NHibernate, чтобы получить доступ к различным столбцам?

Если да, приведите пример.


Решение (основанное на предложениях Дэвида Осборна и mxmissile): не использовать наследование . Я использую реализацию общего интерфейса вместо наследования классов. Рабочий код ниже:

public interface INodeLite {
  long Id { get; set; }
  string Code { get; set; }
}

public class NodeEntityLite : INodeLite {
  public virtual long Id { get; set; }
  public virtual string Code { get; set; }
}

public class NodeEntity : INodeLite {
  public virtual long Id { get; set; }
  public virtual string Code { get; set; }
  public virtual string NOTE { get; set; } // type:clob
}
...
public void Override(AutoMapping<NodeEntityLite> mapping) {
    mapping.Table("NODES");
}
...
public void Override(AutoMapping<NodeEntity> mapping) {
    mapping.Table("NODES");
    mapping.Map(e => e.NOTE).CustomType("StringClob").CustomSqlType("NCLOB");
}

1 Ответ

0 голосов
/ 18 января 2019

Независимо от наследования, NH может отображать разные типы в одну и ту же таблицу. Я сделал это, хотя и без наследства.

Вы сможете удалить эту строку из переопределения NodeEntityLite и достичь ее:

mapping.UseUnionSubclassForInheritanceMapping();

Если это окажется безуспешным, вам, возможно, придется настроить автоподстановку дальше. Хотя это определенно возможно.

...