【问题标题】:How do I get the entity type on an object that may be a NHibernate proxy object?如何获取可能是 NHibernate 代理对象的对象的实体类型?
【发布时间】:2010-09-20 21:57:10
【问题描述】:

我有一个基类DomainObject 用于我在NHibernate 中使用的所有业务对象。它包含Id 属性。

public abstract class DomainObject
{
    public virtual int Id { get; private set; }
}

我想写一个IEqualityComparer 来比较我的域对象。如果两个对象具有相同的Id 并且是相同类型的对象,则它们应该相等。但是,当我使用GetType() 获取对象的类型时,它将返回 NHibernate 代理类型。所以这段代码:

bool IEqualityComparer.Equals(object x, object y)
{
    // null checking code skipped here
    if(x is DomainObject && y is DomainObject)
    {
            return ((DomainObject) x).Id == ((DomainObject) y).Id
                    && x.GetType() == y.GetType();
    }
    return x.Equals(y);
}

不能正常工作,因为x is Asset的类型是y is AssetProxy21879bba3e9e47edbbdc2a546445c657的类型。

那么,如何获取可能是 NHibernate 代理对象的对象的实体类型?即在上面的示例中 Asset 而不是 AssetProxy21879bba3e9e47edbbdc2a546445c657?

【问题讨论】:

  • 我 99% 确定这是重复的,但我现在懒得去搜索它 :-)
  • 请给我看它重复的那个,我在stackoverflow上找遍了。

标签: nhibernate


【解决方案1】:

您可以通过以下方式获取代理的真实类型:

NHibernateUtil.GetClass(x);

或者您可以向DomainObject 添加一个方法,例如:

public virtual Type GetTypeUnproxied()
{
    return GetType();
}

这真的很漂亮,不直接依赖于 NHibernate。

或者,可以通过说您需要获取真实对象而不是代理来解决问题,如果会话方便,可以通过以下方式完成:

session.PersistenceContext.Unproxy(x);

正如另一个答案中提到的,如果您尝试实现 equals,最好查看Sharp architecture implementation of Equals

【讨论】:

  • 请注意,如果您使用的是 Castle Windsor,GetClass 可能会返回代理类型。请参阅此线程以获取另一种解决方法:stackoverflow.com/a/1420816/348841
【解决方案2】:

要获取真实对象而不是代理,您可以使用

session.PersistenceContext.Unproxy(proxyObject)

但我认为您应该查看 Sharp architecture implementation 的 Equals。

【讨论】:

  • 需要注意的是,他可能对github.com/codai/Sharp-Architecture/blob/master/src/SharpArch/… 中的GetTypeUnproxied() 方法更感兴趣——但是+1 以获得良好的参考实现。
  • 在这种情况下,我在此代码中实际上没有可用的会话。感谢 Sharp 架构中对 Equals 的引用,它不适用于我,因为我正在为测试编写 equals,因此它不必处理所有情况,但它仍然是一个很好的参考。感谢 Dan 提供 GetTypeUnproxied() 代码的链接,这才是我更感兴趣的。
【解决方案3】:

您可以按照here 的描述实现后门属性来获取实际的非代理实例。

【讨论】:

    【解决方案4】:

    我在制作项目中采用了不同的方法。我只是有一个全局 HiLow Id-Generator,它为所有类型生成唯一的 Id,然后我可以:

    // in DomainEntity
    public override bool Equals(object obj)
    {
        var other = obj as DomainEntity;
        if (Id == 0) // IsTransient()
            return ReferenceEquals(this, other);
        else
            return (other != null) && (Id == other.Id);
    }
    
    // Comparer
    bool IEqualityComparer.Equals(object x, object y)
    {
        return object.Equals(x, y);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-27
      • 2014-11-04
      • 2010-11-27
      • 1970-01-01
      • 2015-11-28
      • 2013-11-10
      • 2011-03-12
      • 1970-01-01
      相关资源
      最近更新 更多