不确定nHibernate Proxies的'is'行为

时间:2011-07-15 12:05:43

标签: c# nhibernate fluent-nhibernate proxies

我有一种情况需要确定继承的类是否是特定的继承类,但模型中预期的类型是基类,并使用nHibernate / {{1使用Fluent nHibernate层次结构。所以我的结构看起来有点像..

Table Per Concrete Class

所以基本上,这里发生的是这个。 class Mutation : Entity { virtual Aspect Aspect { get; set; } virtual Measurement Measurement { get; set; } } abstract class Measurement : Entity { // does nothing on its own, really. } class Numeric : Measurement { virtual int Value { get; set; } // may have some other properties } class Observable : Measurement { virtual Aspect Aspect { get; set; } } 期望指向一种数据和一种测量变化(可能有其他方式来改变数据,而不仅仅是平数)。那么我会有一个只需要Mutation的对象,并将每个后续类型的IList<Mutation>映射到它自己的特定表,与基础Measurement类共享Identity。到目前为止工作正常。

现在Measurement的不同之处在于它不存储自己的值,而是再次指向可能有自己的一组突变和变化的另一个Observable。我们的想法是始终从预期的源检索值,而不是在数据库中保存为平值。 (有理由希望这种行为超出了本问题的范围)

那么,我的想法基本上是进行这样的评估..

Aspect

那不起作用。我仍然得到foreach(var measurement in list) { if(measurement is Observable){ // then we know to lookup the other value } } 的代理结果。但是在不使用nHibernate的情况下,相同的代码在独立的MeasurementProxy应用程序中运行良好,因此我对代理问题充满信心。

然后我将以下方法添加到我的基础C#类......

Entity

现在,如果我做 /// <summary> /// Unwrap the type from whatever proxy it may be /// behind, returning the actual .NET <typeparamref name="System.Type"/>. /// </summary> /// <returns> /// A pure <typeparamref name="System.Type"/> that is no longer proxied. /// </returns> public virtual Type Unwrap() { return GetType(); } ,我会得到正确的类型,但同样的评估......

Console.WriteLine(measurement.Unwrap());

仍然无法运作。它永远不会运行。任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:2)

这是因为Unwrap()会返回Type,因此measurement.Unwrap() is Observable始终为false,而measurement.Unwrap() is Type始终为true

改为使用typeof运算符和引用相等:

if (measurement.Unwrap() == typeof(Observable)) {
    // Then we know to lookup the other value.
}

答案 1 :(得分:0)

检查Hamidi的答案是不够的。只要在映射中添加一些惰性属性,例如:

<property name="Description" type="StringClob" not-null="false" lazy="true"/>

Unwrap方法将失败,因为对于使用延迟属性的类型,对象始终是代理,并且检查

if (measurement.Unwrap() == typeof(Observable)) {
    // Then we know to lookup the other value.
} 

将失败,因为Unwrap将返回Proxy的类型,而不是预期的类型。

我使用以下方法检查实体类型:

public virtual Type GetEntityType()
{
    var type = GetType();
    // Hack to avoid problem with some types that always be proxy. 
    // Need re-evaluate when upgrade to NH 3.3.3
    return type.Name.EndsWith("Proxy") ? type.BaseType : type;
}

public virtual bool IsOfType<T>()
{
    return typeof(T).IsAssignableFrom(GetEntityType());
}

并且检查变为:

if (measurement.IsOfType<Observable>()) {
    // Then we know to lookup the other value.
}

正如您在代码注释中看到的,这是NH 3.1和城堡代理的攻击:城堡动态代理类型总是以代理结束,因此我利用此签名来检测对象是否是代理。我的项目仍然停留在NH3.1上,所以我不确定NH3.3需要对该方法进行哪些更改。