2009-05-05 7 views
1

NHibernateを使用してマッピングされたエンティティを保存しようとしましたが、基になるテーブルにNULLを許可しないカラムがあり、それがマッピングされていないのは、問題の列がレガシーアプリケーションをサポートしており、アプリケーションとの関連性がないからです。そのため、レガシープロパティでエンティティを汚染しないようにします。NHibernateはインターセプタのマッピングされていないカラムを追加します

私は私のクラスの中でプライベートフィールドを使うことができると知っていますが、これはまだ私にとっては厄介です。 read私はNHibernateインターセプタを使用し、OnSave()メソッドをオーバーライドして、エンティティが保存される直前に新しい列を追加することができます。これは、私のインターセプターのOnSaveのtypesパラメーターにNhibernate.type.ITypeのインスタンスを追加する方法を試すことができないため、難しいことです。

私のエンティティは、おおよそ次のようになります。

public class Client 
{ 
    public virtual int Id { get; set; } 
    public virtual int ParentId { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Phone { get; set; } 
    public virtual string Email { get; set; } 
    public virtual string Url { get; set; } 
} 

そして、私の迎撃

public class ClientInterceptor : EmptyInterceptor 
{ 

    public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types) 
    { 
     if (entity is Client) 
     { 
      /* 
       manually add the COM_HOLD column to the Client entity 
      */ 
      List<string> pn_list = propertyNames.ToList(); 
      pn_list.Add("COM_HOLD"); 
      propertyNames = pn_list.ToArray(); 

      List<Object> _state = state.ToList(); 
      _state.Add(false); 
      state = _state.ToArray(); 

      //somehow add an IType to types param ?? 

     } 
     return base.OnSave(entity, id, state, propertyNames, types); 
    } 
} 

誰もが適切にこれを行う方法上の任意のアイデアを持っていますか?

答えて

1

ステファンのように私は実際にこれをしたことがないので、私は確かに言えませんが、typesアレイにNHibernate.Type.BooleanTypeを追加できますか?

List<IType> typeList = types.ToList(); 
typeList.Add(new BooleanType()); 
types = typesList.ToArray(); 

EDITはい、それはあなたが正しいように見える

。型はinternalコンストラクタを持ちます。私はいくつかの掘削を行なったし、TypeFactoryが見つかりました: デフォルトITYPEが十分に良好であれば

アプリケーションは NHibernate.NHibernateUtilに静的 メソッドと定数を使用する必要があります。たとえば、TypeFactoryは、文字列の長さを255ではなく300にする必要がある場合にのみ、 を使用します。 この時点で、NHibernate.Stringは正しいITypeを取得しません。代わりにTypeFactory.GetString(300)を使用し、 のITypeへの参照を保持するローカル変数を保持します。

何をしたいことはNHibernateUtilあるようなので、それが見えます:

は NHibernateは組み込み型の全範囲へのアクセスを提供します。 IType インスタンスを使用して、クエリパラメータに値 をバインドできます。新しいBlobとClobのための工場 もあります。

typeList.Add(NHibernateUtil.Boolean); 
+0

私は恐らくNHibernate.Type.BooleanTypeであり、その名前空間内の他のものはすべて、通常の方法で新しい名前空間には不可能な私的なコンストラクタを持っています。私はあなたがオブジェクトを作成するためにいくつかの他のNHibernate APIを使用する必要があると思います。 –

+0

NHibernateUtil.Booleanを試してみてください。 –

+0

ありがとうスチュアート - それはトリックをしました。自分のエンティティクラスからプライベートフィールドを削除しました。テーブルに問題なく挿入できます。 –

1

個人的に私はそれほど複雑ではありません。私はプライベートプロパティを追加し、デフォルト値を割り当てます - 完了しました。また、データベース内のデフォルト値を考慮することもできます。それ以外は何もする必要はありません。

private virtual bool COM_HOLD 
{ 
    get { return false; } 
    set { /* make NH happy */ } 
} 

私はデータベース・トリガーを作成することを検討しています。インターセプタを使用すると、データアクセスレイヤを「汚染する」ためです。それはそれを不安定にする可能性があります。に奇妙な問題があります。

+1

こんにちはStefan - フィードバックありがとうございます。悲しいことに私はデータベースを変更することはできません。 COM_HOLDは私のアプリケーションのロジックに何も意味しないので、自分のエンティティにプロパティを追加する必要がないのが理想的です。私の質問では、dbのテーブルの必須の列です。 –

+0

私はあなたが意味することを理解しています。私は最も簡単な解決方法を提案するだけです。私有財産は非常に簡単で多くを傷つけることはありません。傍受者をめちゃくちゃ嫌うことはまったく容易ではありません。 –

関連する問題