如何在可能是NHibernate代理对象的对象上获取实体类型?

时间:2010-09-20 21:57:11

标签: nhibernate

我为NHibernate使用的所有业务对象都有一个基类DomainObject。它包含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

4 个答案:

答案 0 :(得分:22)

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

NHibernateUtil.GetClass(x);

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

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

这很光滑,不直接依赖于NHibernate。

或者,可以通过说你需要获得真正的对象而不是代理来解决问题,如果会话很方便,可以使用:

session.PersistenceContext.Unproxy(x);

正如另一个答案中所提到的,如果你想要实现平等,最好查看Sharp architecture implementation of Equals

答案 1 :(得分:2)

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

session.PersistenceContext.Unproxy(proxyObject)

但我认为你应该看看Sharp architecture implementation等于Equals。

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

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

// 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);
}