1

NHibernateを使用してマップされたエンティティを保存しようとしていますが、基になるテーブルにnullを許可しない列があり、ドメインオブジェクトにマップされていないため、データベースへの挿入が失敗します。マップされていない理由は、問題の列がレガシーアプリケーションをサポートしており、アプリケーションとの関連性がないためです。したがって、レガシープロパティでエンティティを汚染したくないのです。

クラス内でプライベートフィールドを使用できることはわかっていますが、それでも私には不快感を覚えます。NHibernateインターセプターを使用し、OnSave()メソッドをオーバーライドして、エンティティが保存される直前に新しい列を追加できることを読みました。Nhibernate.type.ITypeのインスタンスをインターセプターのOnSaveのtypesパラメーターに追加する方法がわからないため、これは難しいことがわかります。

私のエンティティは大まかに次のようになります。

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);
    }
}

誰かがこれを適切に行う方法について何かアイデアがありますか?

4

2 に答える 2

1

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

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

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

于 2009-05-05T11:12:34.893 に答える
1

私は実際にこれを行ったことがないので、確かなことは言えません (Stefan のように、私もプライベート プロパティを追加することを好みます) が、配列に aNHibernate.Type.BooleanTypeを追加することはできますか?types

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

編集

はい、あなたが正しいようです。型にはinternalコンストラクターがあります。私は掘り下げて見つけましたTypeFactory

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

したがって、あなたが望むのは次のようになりますNHibernateUtil:

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

typeList.Add(NHibernateUtil.Boolean);
于 2009-05-05T16:11:02.927 に答える