В устаревшей БД есть таблица 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");
}