6

ランタイム配列に基づいて値をチェックするFluentNHibernateLinqクエリがあります。基本的な例は次のようになります。

var array = [1,2,3,4,5,6];
using (var session = SessionProvider.SessionFactory.OpenSession())
{
  return session.Query<MyObject>().Where(x => array.Contains(x.CompareVal)).ToList();
}

生成されたSQLステートメントは次のようになると思います。

SELECT CompareVal, Column1, Column2
FROM MyObject
WHERE CompareVal IN (1,2,3,4,5,6)

ただし、代わりに私が見つけたのは、生成されたSQLステートメントがWHERE句(プロファイラーで監視することで証明された)を発行し、テーブル全体を選択し、すべてのデータを取得するとメモリ内でフィルターを実行しているように見えることです。

注意点-私には、これらすべての呼び出しが行われるGenericRepositoryクラスがあります。Queryメソッドは次のとおりです。

public IList<T> Query(Func<T, bool> criteria)
{
  using (var session = SessionProvider.SessionFactory.OpenSession())
  {
    return session.Query<T>().Where(criteria).ToList();
  }
}

明らかに、これ(where句の欠如)は、大量のデータを含むテーブルでは受け入れられません。NHibernateがWHERE句を使用してクエリを正しく生成し、リポジトリの一般的なパターンを維持するように強制するにはどうすればよいですか?

4

3 に答える 3

3

Queryメソッドを次のように変更した場合、違いはありますか?

public IList<T> Query(Expression<Func<T, bool>> criteria)
{
  using (var session = SessionProvider.SessionFactory.OpenSession())
  {
    return session.Query<T>().Where(criteria).ToList();
  }
}

これは私が通常一般的なクエリを進める方法です:

    public List<TOut> GetEntitiesLinq<TIn,TOut>(Expression<Func<IQueryable<TIn>,IQueryable<TOut>>> myFunc)
    {
        var t = (myFunc.Compile())(_session.Query<TIn>()) ;
        return t.ToList();
    }

それなら私があなたの場合にそれをどのように使うか:

var myObjList = myQueryManager.GetEntitiesLinq<MyObject,MyObject>(x=>x.Where(myObj => array.Contains(myObj.CompareVal)));

これがお役に立てば幸いです

于 2013-02-01T14:54:22.707 に答える
2

任意を使用:

 return session.Query<MyObject>().Where(x => array.Any(y => y == x.CompareVal)).ToList();

リポジトリパターン(プレーンなFuncを使用)は、クエリをリストに自動的に具体化します。何かを延期して実行する場合は、IQueryableを使用し、Funcのみを使用しないでください。

注意点-私には、これらすべての呼び出しが行われるGenericRepositoryクラスがあります。Queryメソッドは次のとおりです。

public IList<T> Query(Func<T, bool> criteria)
{
  using (var session = SessionProvider.SessionFactory.OpenSession())
  {
    return session.Query<T>().Where(criteria).ToList();
  }
}

あなたのリポジトリは、NHibernateによって箱から出してすでに提供されているものを模倣しているだけです

于 2013-02-01T14:32:28.487 に答える
0

代わりにQueryOverとWhereRestrictionOnを使用できますか?

session.QueryOver<MyObject>().WhereRestrictionOn(o => o.CompareVal).IsIn(array).List();
于 2013-02-01T14:30:07.427 に答える