我有一种情况需要确定继承的类是否是特定的继承类,但模型中预期的类型是基类,并使用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());
仍然无法运作。它永远不会运行。任何人都可以帮助我吗?
答案 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需要对该方法进行哪些更改。