2016-03-29 14 views
1

nHhibernateを使用してメモリコレクションによってdbテーブル(コンポジットキーId1とId2)をフィルタリングします。NHibernate QueryOverフィルターbyコレクション

class Item{ int Id1; int Id2; } 

var collection = new List<Item>(); 

var list = _session 
    .QueryOver<MyDbTable>() 
    .Where(x => collection.Any(y => y.Id1 == x.Id1 && y.Id2 == x.Id2)) 
    .List(); 

私はこれを行うことによって取得エラー「が認識されないメソッドの呼び出し:System.Linq.Enumerable:ブールどれ」です。 FirstOrDefaultメソッドを使用して結果をnullと比較しようとしましたが、機能しません。

答えて

3

NHibernateでLinqメソッドを使用することはできません。

プロパティがコレクション内にあるかどうかを確認するには、IsInメソッドを使用できますが、単一のプロパティがコレクション内にあるかどうかを確認したくない場合は、複合キーを探しています。

はあなたの問題を解決するために、あなたの制約を構築するために collectionを繰り返すことができます。それに

var disjunctionOptions = new Disjunction(); 

foreach (var item in collection) 
{ 
    var conjunction = new Conjunction(); 
    conjunction.Add<MyDbTable>(x => x.Id1 == item.Id1); 
    conjunction.Add<MyDbTable>(x => x.Id2 == item.Id2); 

    disjunctionOptions.Add(conjunction); 
} 

var list = _session 
    .QueryOver<MyDbTable>() 
    .Where(disjuntionOptions) 
    .List(); 

はあなたが複合キーを持つクエリの正しい結果を持っています。

IsIn単一プロパティがcolletion(または配列)内にあるかどうかをチェックすることです。コンポジットキーを使用しているため、別々に(各プロパティ内で)使用すると間違った結果が得られます。

+0

私のバージョンは動作しないと私は同意しますが、とにかく別の解決策を探しています。コレクションに100の要素のようなまともなサイズがある場合、またはdisjunctionクエリによって生成されたSQLのサイズが1000であることを認識していますか? –

+0

こんにちは@AlexeyZimarev、SQLクエリの長​​さの上限は65,536 *ネットワークパケットサイズ(デフォルトは4KB)です。 2100パラメータの制限は、SQLクエリの長​​さよりも前になります。たとえば、2100を超える要素を持つコレクションを使用してIsInを使用することはできません。これは私のソリューションの特有の問題ではなく、このケースでは最小限のパラメータを使用しています。私はandsとorsのクエリが長くなることに同意しますが、パラメータの数は増えません。もちろん、必要に応じてHQLを使用することもできます。 –

1

おそらく、あなたがと信じている間に混乱してQueryOver APIを使用していますか?この場合、linq2nhを使用するためにコードを変更:ISession.QueryNHibernate.Linq名前空間で定義された拡張メソッドであるよう

using NHibernate.Linq; 
... 

var collection = new List<Item>(); 

var list = _session 
    .Query<MyDbTable>() 
    .Where(x => collection.Any(y => y.Id1 == x.Id1 && y.Id2 == x.Id2)) 
    .ToList(); 

usingは、QueryQueryOverを切り替えるために必要とされます。 QueryOverの代わりにLinq APIを使用する場合は、Listメソッド呼び出しをToListに変更する必要があります。

関連する問題