【问题标题】:NHibernate Criteria: howto exclude certain mapped properties/collections?NHibernate 标准:如何排除某些映射的属性/集合?
【发布时间】:2011-07-21 18:13:44
【问题描述】:

这是我的(简化的)模型:Ticket -> Customer Callback (s)

我已经映射了我的票证,因此当它加载时,回调也是如此。

        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();

现在..我们需要向代理显示他们的回调列表 - 只是他们的回调。 -- 当我使用回调的条件进行查询时,我无法阻止票证(以及随后的整个图表,包括其他集合)被加载。我之前曾尝试设置 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()
            ;
        // ...
     }

【问题讨论】:

    标签: nhibernate properties projection icriteria


    【解决方案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 类来封装此查询的结果。而不是使用现有的实体类。

    【讨论】:

    • 再次感谢瓦迪姆!我会试一试,让你知道它是怎么回事。一件事:我需要将 FetchMode 保留在那里吗? (我对投影的理解是,只有列表中指定的那些属性才会被查询。)
    • @Joe,没错,您不需要 FetchMode,因为您不会获取实体,而是获取一堆属性。
    • 我不确定它为什么要尝试将回调实例转换为对象数组?我需要使用独立的标准吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 2019-06-06
    • 2013-06-10
    • 2012-09-28
    • 2011-03-02
    • 2018-03-12
    相关资源
    最近更新 更多