3

私が使用している: NHibernate、NHibernate.Linq、および SQL Server Express 2008 上の Fluent NHibernate。参照されたプロパティ (多対一マッピング) の述語を使用してエンティティを選択しています。fetch=join、unique=true、lazy-load=false があります。log4net ログを有効にすると、そのようなクエリが実行されると、2 つの同一の SQL クエリがログに記録されます。クエリを実行すると 1 行が返され、IQueryable.Single 拡張メソッドを使用しようとすると、複数の行が返されたことを示す例外がスローされます。また、標準の IQuery.UniqueResult メソッドを使用して同じ結果でクエリを実行しようとしましたが、最終的にログに記録され、実際にクエリを 2 回実行してから、複数の行があることを示す例外をスローしましたが、管理スタジオで実際のクエリを実行すると、返されるのは 1 つだけです。 1つの結果。ロギングを無効にすると、同じエラーが発生します。

エンティティとマッピングは次のように宣言されます (適切なアクセス修飾子とメンバー型の差異が暗示されます)。

class User
{
    int ID;
    string UserName;
}

class Client
{
    int ID;
    User User;
    Person Person;
    Address Address;
}

class UserMap : ClassMap<User>
{
    public UserMap()
    {
       Id(x => x.ID);
       Map(x => x.UserName);
    }
}

class ClientMap : ClassMap<Client>
{
    public ClientMap()
    {
       Id(x => x.ID);
       References(x => x.User).Unique();
       ...
    }
}

次に、次のようなクエリを呼び出します。

ISession s = GetNHibernateSession();

...

var client = s.Linq<Client>().SingleOrDefault(x => x.User.ID = 17);

or

var client = s.Linq<Client>().Where(x => x.User.ID = 17);

or

var client = s.CreateQuery("from Client as c where c.User.ID = 17").UniqueResult<Client>();

いずれの場合も、2 つの同一のクエリを実行します。遅延読み込みを有効にすると、クライアントは再び 2 つのクエリを使用して読み込まれますが、Person などのメンバーにアクセスすると、追加のクエリが 1 つだけ実行されます。

これは、Fluent が不適切なマッピングを生成した結果である可能性がありますか? または、SQL Server Express エディションが NHibernate によって適切に使用されていませんか?

4

3 に答える 3

5

この問題は、私が宣言した別のマッピングが原因でした。関連するマッピングを持つ Client から継承するクラスがありました。これが、NHibernate が 2 回クエリを実行する原因でした。Linq() を使用すると、クライアント自体ではなくサブクラスが返されたため、これに気付きました。継承とマッピングのこの特定のインスタンスは、私の側の設計上の欠陥であり、問​​題全体の根源でした!

于 2009-03-11T23:49:49.883 に答える
1

何が起こっているのかをより詳細に表示するには、優れたNHibernateプロファイラーを使用してみてください。30 日間の試用版ライセンスが付属しており、ベータ版ではライセンス コスト全体の割引があります。

于 2009-03-11T09:24:41.553 に答える
1

NHibernate は SQL Express で何の問題もありません。私は SQL Express をかなり広範囲に使用してきました。同様に、Fluent NHibernate がこの単純なシナリオで無効なマッピングを生成する可能性はほとんどありません (前代未聞ではありません)。

暗闇の中のショットですが、NHibernate は Id という名前を識別子名として予約していると思います。そのため、クエリで Id を見ると、実際の結合されたエンティティではなく、外部キーを見るだけでよいことがわかります。おそらく、ID の代わりに ID の名前を付けたことで、それがうまくいかなかったのでしょうか?

于 2009-03-11T08:58:43.737 に答える