2009-04-15 10 views
2

NHibernateを使ってほとんどすべてがイベントを持っているエンティティ階層をマップしようとしています。NHibernateはイベントを仮想にする必要がありますか?

Core.Domain.Entities.Delivery:メソッド remove_Scheduledは仮想である必要があり

配達が実体であるしかし、セッションファクトリを構築しようとすると、私は次のようなエラーメッセージを取得します私のドメインモデルでは、という予定のイベントがあります。イベントは仮想的に宣言することができないので、私はここでどのように進めるべきかについて迷っています。なぜNHibernateは事態を仮想的にする必要がありますか?

答えて

0

あなたのマッピングはどのように見えますか? イベントをマップしましたか?

私は以前この問題に遭遇していませんでしたが、私のクラスマッピングで常に 'lazy = false'属性を指定して、プロパティを仮想として宣言する必要はありません。あなたが遅延ロードを使用する場合NHibernateのは、実行時にエンティティのためのプロキシオブジェクトを作成しますので、

<class name="MyClass" table="MyTable" lazy="false"> 
</class> 
+0

私もイベントをマッピングすることが可能であったとは思いませんでした。あなたは常にlazy = falseを指定しますか?物事は、私の状況で絶対に必要な怠惰なローディングです。すべての状況でどのエンティティをロードするかを指定するのは禁止されます。 – Jimit

+0

クラスレベルでlazy = falseを指定します。そうすることで、私がしたくないときに自分のプロパティを仮想化する必要はありません。 欠点は、NHibernateはオブジェクトを取得するときに動的プロキシを使用しないことです。たとえば、動的プロキシを使用してオブジェクトを取得する場合、NHibernateはオブジェクトのIDのみを設定します。オブジェクトのプロパティのいずれかにアクセスする場合にのみ、オブジェクト全体がロードされます。 しかし、これはコレクションの遅延読み込みには影響しません。 –

2

公共のメンバーが仮想宣言する必要があります(私は私のビジネスモデルのdoesntのは、これを必要とする場合、仮想としての特性を宣言するために好きではないので)。遅延ロードを使用しないでください。イベントを仮想として宣言してください。これはあまり一般的ではありませんが、可能です。

NHibernateはすべての遅延ロードされたエンティティのプロキシクラスを作成し、エンティティが参照されているがまだロードされていない場所でプロキシクラスを使用します。このプロキシにアクセスすると、実際のエンティティがデータベースからロードされます。このアプローチでは、実行時にエンティティクラスから継承し、パブリックメンバをオーバーライドする必要があります。したがって、このメンバを仮想にする必要があります。

また、別の解決策があります。クラス宣言にproxy="ISomeInterface"を追加できます。プロキシが指定されたインターフェースを実装するだけで、仮想メンバーは必要ありません。

+0

ドメインモデルはVB.NETで記述されています。私が知る限り、イベントをVBで仮想(オーバーライド可能)として宣言することはできません。 – Jimit

+0

私は仮想メンバーの要件を理解しています。なぜ、NHibernateがイベントを仮想にする必要があるのか​​分かりません。イベントのadd_ *メソッドとremove_ *メソッドは、単にイベントのハンドラを追加したり削除したりするだけです。彼らは州にアクセスしないので、仮想である必要はありません。 – Jimit

+0

NHibernateのソースコードを確認しましたが、ProxyTypeValidator.CheckAccessibleMembersAreVirtual(System.Type型、IListエラー)はエラーが発生した場所です。このメソッドは、GetTypeを除くクラスのすべてのメソッドをチェックし、それらが仮想であることを検証します。 – Jimit

1

遅延読み込みオブジェクトにINotifyPropertyChangedを実装する際に同じ問題が発生しました。問題は実際には2つの異なる.NETインスタンスを処理するため、実際のインスタンスでNPCイベントを発生させたときに、プロキシへの参照からNPCイベントを受け取らないようにすることです。仮想化することで、プロキシはこのイベントを「転送」することができます。残念ながら、VB.NET(2005)ではイベントを仮想/オーバーライドとして定義することはできません。したがって、VBの問題を回避するためにこれらの仮想イベントのみを実装する基本クラスを持つC#プロジェクトを導入する必要がありました。 https://forum.hibernate.org/viewtopic.php?f=25&t=990162&start=0

私たちの方法では、プロキシの透過性が低下するため、他の方法もあります。また、遅延ロードされたオブジェクトを初期化する必要があるときにセッションを自動再接続する領域では、やや苦痛があります。

よろしく、 テオ

関連する問題