1

我有一种情况,我需要确定一个继承类是否是一个特定的继承类,但模型中预期的类型是基类,它是使用nHibernate/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类共享。到目前为止效果很好。

现在 anObservable的不同之处在于它不存储自己的值,而是再次指向另一个Aspect可能具有自己的一组突变和变化的值。这个想法是该值将始终从预期的源中检索,而不是作为平面值保存在数据库中。(想要这种行为是有原因的,超出了这个问题的范围)

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

foreach(var measurement in list) {
   if(measurement is Observable){
      // then we know to lookup the other value
   }
}

那没有用。我仍然得到 just 的代理结果MeasurementProxy。但是相同的代码在C#不使用 nHibernate 的独立应用程序中也能正常工作,所以我非常有信心认为问题出在代理上。

然后我将以下方法添加到我的基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());我会得到正确的类型,但同样的评价......

foreach(var measurement in list) {
   if(measurement.Unwrap() is Observable){
      // then we know to lookup the other value
   }
}

仍然无法正常工作。它从不运行。有谁可以帮我离开这里吗?

4

2 回答 2

2

那是因为Unwrap()返回 a 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.
}
于 2011-07-15T12:09:09.117 回答
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 和 Castle Proxy 的一个 hack:Castle 动态代理类型总是以 Proxy 结尾,所以我利用这个签名来检测对象是否是代理。我的项目仍然使用 NH3.1,所以我不确定 NH3.3 需要对该方法进行哪些更改。

于 2013-08-23T09:31:04.297 回答