这是我的(简化)模型:票证 - >客户回调
我已将我的Ticket映射,以便在加载时,回调也是如此。
base.HasMany<TechSupportCallback>(x => x.Callbacks)
.KeyColumn(Fields.TRACKED_ITEM_ID)
.Not.LazyLoad()
.Inverse()
.Cache.ReadWrite();
这不是延迟加载,否则当Web服务尝试序列化(和加载)代理时,我将得到“没有加载实体的会话”。 (使用存储库获取数据。)
它也是双向的..(在CallbackMap中)
base.References(x => x.Ticket)
.Column(Fields.TRACKED_ITEM_ID)
.Not.Nullable();
现在..我们需要向代理显示他们的回调列表 - 只是他们的回调。 - 当我使用Criteria查询回调时,我无法阻止加载Ticket(以及随后的整个图形,包括其他集合)。我以前尝试设置FetchMode.Lazy,然后迭代每个生成的Callback并将Ticket设置为null,但这似乎被忽略了。
// 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()
;
// ...
}
答案 0 :(得分:3)
这听起来像是投影的准确工作。
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类,仅用于封装此查询的结果。而不是使用现有的实体类。