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共有するオブジェクトを作成します。これまでのところ問題なく動作します。IdentityMeasurement

ここで、anObservableは独自の値を格納しないという点で異なりますAspectが、独自の変異と変更のセットを持つ可能性のある別の値を再度指します。値は常に目的のソースから取得され、データベースにフラットな値として保存されないという考え方です。(この質問の範囲を超えたこの動作が必要な理由があります)

それで、基本的にはこういう評価をするのが私の考えでした。

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

それはうまくいきませんでした。私はまだちょうどのプロキシ結果を取得し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()は、を返すためです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

ハミディの答えをチェックするだけでは不十分です。いくつかの怠惰なプロパティをマッピングに追加するとすぐに、たとえば次のようになります。

<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は、予期されたタイプではなく、プロキシのタイプを返すため、失敗します。

エンティティタイプをチェックするために次のメソッドを使用します。

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.
}

コードコメントにあるように、これはNH3.1とCastleProxyのハックです。CastleDynamicProxyタイプは常にプロキシで終わるため、このシグネチャを利用して、オブジェクトがプロキシであるかどうかを検出しました。私のプロジェクトはまだNH3.1で立ち往生しているので、NH3.3でメソッドにどのような変更が必要かわかりません。

于 2013-08-23T09:31:04.297 に答える