Критерии NHibernate: как исключить определенные сопоставленные свойства / коллекции?
Вот моя (упрощенная) модель: Билет -> Обратный звонок (и) клиента
Мой Билет сопоставлен так, чтобы, когда это загружено, Обратные вызовы были также.
base.HasMany<TechSupportCallback>(x => x.Callbacks)
.KeyColumn(Fields.TRACKED_ITEM_ID)
.Not.LazyLoad()
.Inverse()
.Cache.ReadWrite();
Это не ленивая загрузка, потому что в противном случае я получу "нет сеанса для загрузки сущностей", когда веб-служба попытается сериализовать (и загрузить) прокси. (Использование репозиториев для извлечения данных.)
Это также двунаправленный.. (в CallbackMap)
base.References(x => x.Ticket)
.Column(Fields.TRACKED_ITEM_ID)
.Not.Nullable();
Теперь... нам нужно показать агенту список их обратных вызовов - ПРОСТО их обратные вызовы. - Когда я делаю запрос с использованием критериев для обратных вызовов, я не могу предотвратить загрузку билета (и впоследствии всего его графика, включая другие коллекции). Ранее я пытался установить FetchMode.Lazy, затем выполнять итерацию каждого полученного обратного вызова и устанавливать Ticket на ноль, но это, кажется, игнорируется.
// open session & transaction in using (..)
var query = session.CreateCriteria<TechSupportCallback>()
.SetCacheable(true)
.SetCacheRegion("CallbacksByUserAndGroups")
.SetFetchMode("Ticket", FetchMode.Lazy) // <-- but this doesn't work!
.SetMaxResults(AegisDataContext.Current.GetMaxRecordCount())
;
rValue = query.List<TechSupportCallback>();
rvalue.ForEach(x => x.Ticket = null;); // <-- since this is already retrieved, doing this merely prevents it from going back across the wire
tx.Commit();
// usings end (..)
Должен ли я делать это с проекцией вместо этого? Проблема в том, что.. я не смог найти пример проекций, используемых для заполнения сущности, или их список - только для использования в качестве подзапроса дочерней сущности или чего-то подобного для ограничения список родительских объектов.
Я мог бы действительно использовать некоторые рекомендации по этому вопросу.
[РЕДАКТИРОВАТЬ]
Я попытался использовать проекцию как предложено, но:
Я получаю следующее: (это было из-за ошибки, и с тех пор я прекратил использовать кеш, и он работает. http://nhibernate.jira.com/browse/NH-1090)
System.InvalidCastException occurred
Message=Unable to cast object of type 'AEGISweb.Data.Entities.TechSupportCallback' to type 'System.Object[]'.
Source=NHibernate
StackTrace:
at NHibernate.Cache.StandardQueryCache.Put(QueryKey key, ICacheAssembler[] returnTypes, IList result, Boolean isNaturalKeyLookup, ISessionImplementor session)
InnerException:
в
rValue = query.List<TechSupportCallback>();
со списком проекций, определенным как
// only return the properties we want!
.SetProjection(Projections.ProjectionList()
.Add(Projections.Alias(Projections.Id(), ex.NameOf(x => x.ID))) //
.Add(Projections.Alias(Projections.Property(ex.NameOf(x => x.ContactID)), ex.NameOf(x => x.ContactID)))
// ...
)
.SetResultTra...;
rValue = query.List<TechSupportCallback>();
отображается как
public TechSupportCallbackMap()
{
base.Cache.ReadWrite();
base.Not.LazyLoad();
base.Table("TS_CALLBACKS");
base.Id(x => x.ID, Fields.ID)
.GeneratedBy.Sequence("SEQ_TS_CALLBACKS");
base.References(x => x.Ticket)
.Column(Fields.TRACKED_ITEM_ID)
.Not.Nullable();
base.Map(x => x.TrackedItemID, Fields.TRACKED_ITEM_ID)
.Not.Insert()
.Not.Update()
.Generated.Always()
;
// ...
}
1 ответ
Похоже, это работа именно для проекций.
var query = session.CreateCriteria<TechSupportCallback>()
.SetCacheable(true)
.SetCacheRegion("CallbacksByUserAndGroups")
.SetFetchMode("Ticket", FetchMode.Lazy)
.SetMaxResults(AegisDataContext.Current.GetMaxRecordCount())
.SetProjection(Projections.ProjectionList().
.Add(Projections.Alias(Projections.Id(), "Id")
.Add(Projections.Alias(Projections.Property("Prop"), "Prop")))
.SetResultTransformer(Transformers.AliasToBean<TechSupportCallback>())
;
Просто перечислите все свойства, которые вы хотите включить, и исключите сущность Ticket. Вы даже можете создать класс POCO просто для инкапсуляции результатов этого запроса. Вместо того, чтобы использовать существующий класс сущности.