【问题标题】:Nhibernate producing proxy despite HQL fetch尽管 HQL 获取,但 Nhibernate 生成代理
【发布时间】:2012-04-27 22:40:04
【问题描述】:

我有以下 HQL 语句:

select distinct t from TaskEntity as 
inner join fetch t.Case as c
inner join fetch c.Client as client 
inner join fetch c.Matter as matter

然而,尽管 Matter 有一个针对它的 FETCH,它仍然作为代理返回。

我对这个对象的映射如下

References(x => x.Matter).Columns(new[] {"c_client","c_matter" });

我尝试过对此使用 JOIN,但我的问题是从 1 列变为 2 列,因此它不接受映射。

有什么想法吗?

谢谢,

【问题讨论】:

    标签: nhibernate fluent-nhibernate hql fetching-strategy


    【解决方案1】:

    我解决了导致此问题的问题。

    它还解析为复合 ID!

    在项目的早期 Nhibernate 警告说我没有覆盖 Equals 和 GetHashCode,为了规避大量代码更改并促进代码重用,我创建了一个 CompositeBaseEntity 类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Case.Infrastructure
    {
        public class BaseCompositeEntity : BaseEntity
        {
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
    
            public override bool Equals(object obj)
            {
                return base.Equals(obj);
            }
        }
    }
    

    这个类,把 Nhibernate 告诉我要避免的东西放回原处!由于有两个键可以比较相等性,我们必须重写 Equals 和 GetHashCode() 方法,使其变为:

    public override bool Equals(object obj)
            {
                if (obj == null)
                    return false;
                var t = obj as ClientMatterEntity;
                if (t == null)
                    return false;
                if (AccountNumber== t.ClientAcconuntNumber && CaseNumber == t.CaseNumber)
                    return true;
                return false;
            }
    

    这样,Nhibernate 确切地知道应该如何进行比较,然后知道它是否在一级缓存中有那个对象(它会,正如我们指定的 fetch)。

    更多信息可以在这里找到: http://nhforge.org/blogs/nhibernate/archive/2010/07/01/nhibernate-and-composite-keys.aspx

    【讨论】:

      【解决方案2】:

      请注意,您还必须提供正确的 GetHashCode 实现。

      你的 Equals 实现也不是很好。

      此外,这两种方法都应返回“静态”值。我没有看过你的课,但应该是这样的:

      public class TaskEntity
      {
          public int AccountNumber { get; protected set; }
          public int CaseNumber { get; protected set; }
          public Client Client { get; set; }
          public Matter Matter { get; set; }
      
          public TaskEntity(int accountNr, caseNr)
          {
              AccountNumber = accountNr;
              CaseNumber = caseNr;
          }
      
          protected TaskEntity() {} // Needed for NHibernate proxies
      }
      

      我真的建议您尽可能将组件 ID 放在单独的类中。

      此外,请阅读以下有关 override Equal 的文章,因为您当前的实现可能存在缺陷:http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx 特别了解有关继承和基本类型的部分。

      【讨论】:

      • 说我的 equals 实现“不是很好”很好,但你能提供如何改进它的建议吗?我已经编辑了我的答案,提到了 GetHashCode()
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 2010-12-14
      • 1970-01-01
      • 2018-06-25
      • 2019-12-18
      • 1970-01-01
      相关资源
      最近更新 更多