サードパーティのdllのエンティティとの関連付けを作成しようとしています。いくつかの理由で、私はを使用する必要がありますStatelessSession
。それでStatefullSession
動作しますが、ステートレスでは動作しません。アイデアは、サードパーティがテーブルを追加し、メインテーブルにクエリを実行するときにそのデータをフェッチできるようにすることです。
私には3つのプロジェクトがあります。メインプロジェクト、IExtender
インターフェイスを備えたモデルプロジェクト、およびExtender
クラスを備えたサードパーティプロジェクト(メインプロジェクトによって参照されていない)です。
私のデータスキーマ:
Table Data
Id INT identity,
more fields...
Table Extender
Id INT PK, FK from Data
Name NVARCHAR
more fields...
モデルプロジェクトコード:
public interface IExtender
{
int Id { get; set; }
}
主なプロジェクトコード:
public class Data
{
public virtual int Id { get; set; }
public IExtender Extender { get; set; }
//public IList<IExtender> Extenders { get; set; }
}
メインプロジェクトhbm:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="..." assembly="..." auto-import="true">
<class name="Data" table="Data" lazy="false">
<id name="Id" column="Id" type="int" >
<generator class="identity" />
</id>
<one-to-one name="Extender" foreign-key="Id"
class="Model.IExtender, Model" lazy="false"/>
<!--<bag name="Extenders" cascade="all" inverse="true" lazy="false">
<key column="Id" />
<one-to-many class="Model.IExtender, Model"/>
</bag>-->
</class>
</hibernate-mapping>
サードパーティプロジェクト:
public class Extender : IExtender
{
public virtual int Id { get; set; }
public string Name { get; set; }
}
サードパーティのhbm:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model" assembly="Model" auto-import="true">
<class name="IExtender" table="IExtender" lazy="false" abstract="true">
<id name="Id" column="Id" type="int" >
<generator class="assigned" />
</id>
<union-subclass table="Extender" name="Extension.Extender, Extension" lazy="false">
<property name="Name" column="Name" not-null="true" type="String" />
</union-subclass>
</class>
</hibernate-mapping>
サードパーティプロジェクトは、そのdllをメインプロジェクトのbinフォルダーに配置します。
これで、データを取得するためのコードは次のようになります。
var sessionFactory = new Configuration().Configure()
.AddAssembly(Assembly.LoadFile(System.Environment.CurrentDirectory + @"\Extender.dll"))
.AddAssembly(Assembly.GetExecutingAssembly())
.BuildSessionFactory();
var session = sessionFactory.OpenStatelessSession();
var criteria = session.CreateCriteria<Data>();
var data = criteria.List<Data>().ToList();
Console.WriteLine(data.First().Extender.Id); // fails because Extender is null
を使用するStatefullSession
と、単一のエンティティまたはバッグで正常に機能します。StatelessSession
代わりにとバッグ(および上記のコメント行としてのリスト)を使用すると、エラーが発生します。
ステートレスセッションでコレクションをフェッチすることはできません
をバッグから取り出すと、lazy="false"
次のエラーが発生します(コレクションが仮想であるかどうかに関係なく)。
Initializing [MyProject.Data#1]-ロールのコレクションを遅延初期化できませんでした:MyProject.Data.Extenders、セッションまたはセッションが閉じられていません
編集:NHibernateバージョンを最新にアップグレードし、バッグを使用すると機能するようになりましたが、1対1の関係を持つ単一のエンティティを使用すると常にnullになります。
ちなみに、エラーの有無に関係なく、最後のSQLクエリでExtender
テーブルが正しく結合されていることがわかります。
ご協力いただきありがとうございます。