NHibernate Criteria:如何排除某些映射的属性/集合?

时间:2011-07-21 18:13:44

标签: nhibernate properties projection icriteria

这是我的(简化)模型:票证 - >客户回调

我已将我的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()
            ;
        // ...
     }

1 个答案:

答案 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类,仅用于封装此查询的结果。而不是使用现有的实体类。