0

次のクエリがあります。

MyRepository.Query<MyObject>().SingleOrDefault(x => x.AProperty == aValue);

正しい MyObject を返しますが、ますます時間がかかり始めています。SQL Server Profiler を調べたところ、MyObject および関連オブジェクトのデータベースから 1 行と 1 行を選択することで、すべての MyObjects がデータベースに読み込まれていることがわかりました。データベースが大きくなると、非常に単純なクエリに対して何千もの選択が行われるようになります。

一方、このクエリ:

Session.QueryOver<MyObject>().Where(x => x.AProperty == aValue).SingleOrDefault<MyObject>()

すべてをロードするわけではありません (数千ではなく単一の select ステートメントを作成します)。

なんで?すべてをロードしないようにクエリに指示する方法はありますか? それとも、これがLinqクエリの仕組みですか? 私が尋ねる理由は、すべてのクエリが Query を使用して作成されるアプリケーションを持っているからです。QueryOver に変更するには、多少の作業が必要です。何か案は?

いくつかの詳細:

  • クエリは、NHibernate.Linq 名前空間 (NHibernate v 3.1.0.4000) の拡張メソッドです。
  • FluentNHibernate の私のバージョンは 1.2.0.712 です
  • 私はこの規則を持っています: Conventions.Add(FluentNHibernate.Conventions.Helpers.DefaultLazy.Never());
4

1 に答える 1

0

これを1日以上見た後、ようやく問題に気づきました。本当に簡単ですが、質問の情報から答えるのは難しいです。他の誰かが同じことを経験した場合、これが正しい答えです。

MyRepository には次のようなメソッドがあります。

public List<T> Query<T>() where T : DomainEntity
{
    using (var session = _sessionSource.CreateSession())
    {
        using (var transaction = session.BeginTransaction())
        {
            var result = session.Query<T>();
            transaction.Commit();
            return result.ToList();
        }
    }
}

これは、最初にすべてを ( を使用て)ロードsession.Query<T>()してから、結果に対してクエリを実行することを意味します ( を使用) MyRepository.Query<MyObject>().SingleOrDefault(x => x.AProperty == aValue);

もちろん、ひどく悪い。他人のコードをコピーすることは必ずしも賢明ではありません...

それを避ける方法は?クエリをクエリしないでください。

于 2012-06-18T12:51:33.590 に答える