0

編集:より詳細な質問。

私は nHibernate でのバッチ操作、特にInSQL Server の 2100 のパラメーター制限サイズを克服するためのクエリに取り組んでいます。

このために、このコンストラクターを使用してクラスを作成しました (これは非常に単純化されたバージョンです)。

BatchedQuery(session.Query<Foo>(), allValues, (l, e) => l.Contains(e.Id));

...

public BatchedQuery(IQueryable<TEntity> query, IList<TValue> allValues, Expression<Func<IList<TValue>, TEntity, bool>> predicate)
{
   List<TValue> values = ...; // Select a batch from allValues
   ...

   // I want to pass the values to the expression passed in...
   // something like this, without using Compile: 
   // e => predicate.Compile()(values, e)

   // using JKor's method, I tried this...
   ParameterExpression param = Expression.Parameter(typeof(TEntity), "e");
   Expression<Func<TEntity, bool>> expr2 =
       Expression.Lambda<Func<TEntity, bool>>(Expression.Invoke(predicate,
           Expression.Constant(batchOfValues), param), param);

   query = query.Where(expr2);

   // Do something with the query...
}

// Somewhere else..
// This causes the exception
batchedQuery.ToList();

上記により、nHibernate はKeyNotFoundException.

スタック トレースは次のとおりです。

at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at NHibernate.Param.NamedParameterSpecification.SetEffectiveType(QueryParameters queryParameters)
at NHibernate.Param.ParametersBackTrackExtensions.ResetEffectiveExpectedType(IEnumerable`1 parameterSpecs, QueryParameters queryParameters)
at NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.ResetEffectiveExpectedType(IEnumerable`1 parameterSpecs, QueryParameters queryParameters)
at NHibernate.Loader.Loader.CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session)
at NHibernate.Impl.MultiQueryImpl.AggregateQueriesInformation()
at NHibernate.Impl.MultiQueryImpl.get_Parameters()
at NHibernate.Impl.MultiQueryImpl.CreateCombinedQueryParameters()
at NHibernate.Impl.MultiQueryImpl.List()
at NHibernate.Impl.FutureQueryBatch.GetResultsFrom(IMultiQuery multiApproach)
at NHibernate.Impl.FutureBatch`2.GetResults()
at NHibernate.Impl.FutureBatch`2.get_Results()
at NHibernate.Impl.FutureBatch`2.GetCurrentResult[TResult](Int32 currentIndex)
at NHibernate.Impl.FutureBatch`2.<>c__DisplayClass4`1.<GetEnumerator>b__3()
at NHibernate.Impl.DelayedEnumerator`1.<get_Enumerable>d__0.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at NovusERP.Data.Helpers.BatchedQuery`2.ToList() in D:\Short Utilities\Novus\NovusERP\NovusERP.Data\Helpers\BatchedQuery.cs:line 63
at NovusERP.Modules.Payroll.Attendance.AttendanceViewModel.GetEmployees(IList`1 selectedEmployeeIds) in D:\Short Utilities\Novus\NovusERP\NovusERP.Modules\Payroll\Attendance\AttendanceViewModel.cs:line 79
at NovusERP.Modules.Payroll.Attendance.AttendanceViewModel..ctor(MonthYear currentMonth, IList`1 selectedEmployeeIds) in D:\Short Utilities\Novus\NovusERP\NovusERP.Modules\Payroll\Attendance\AttendanceViewModel.cs:line 47
at NovusERP.Modules.Payroll.Attendance.AttendanceView..ctor(MonthYear currentMonth, IList`1 selectedEmployees) in D:\Short Utilities\Novus\NovusERP\NovusERP.Modules\Payroll\Attendance\AttendanceView.xaml.cs:line 18
at lambda_method(Closure , Object[] )
at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()

誰かが私を正しい方向に向けることができますか? どんな助けでも大歓迎です。

よろしく、
ヨゲシュ。

4

2 に答える 2

1

expr1 をコンパイルせずに expr2 を作成したい場合は、組み込みのコンパイラ変換を使用することはできません。これはあなたが望むものです:

Expression<Func<IList<TValue>, TEntity, bool>> expr1 = (l, e) => l.Contains(e.Id);
ParameterExpression param = Expression.Parameter(typeof(TEntity), "e");
Expresssion<Func<TEntity, bool>> expr2 = Expression.Lambda<Func<TEntity, bool>>(Expression.Invoke(expr1, Expression.Constant(values), param), param);
于 2012-06-26T16:13:29.277 に答える
0

他の人がそれから利益を得ることができるように、私は私の答えを投稿しています。

私が望んでいたことを行うための最良の方法は、適切な変更を加えて式全体を使用ExpressionVisitorExpression.Lambdaてコピーすることでした。このクラスは3/3.5の内部クラスであるため、このクラスを3 / 3.5で使用する場合は、このクラス完全な実装を次に示します。ネット上で同じために利用可能なチュートリアルがたくさんあります。

次に、式ツリーを解析および視覚化するためのツールを入手したい場合はExpressionTreeVisualizer、VS2008でサンプルを入手する必要があります。サンプルをVS2010 for.Net4.0に変換してコンパイルする必要があります。Patrick Smacchiaによるこのブログ投稿は、その方法を支援します。

上記のすべてに対する1つの注意点として、nhibernateは、この回答で説明した方法でクエリを変換した後でも、例外をスローします。これは、クエリを将来のクエリに変換して評価しようとした場合にのみ発生します。クエリをfutureに変換しなくても、正常に機能します。私は同じ解決策を探しています。なぜそれが起こっているのか、そして解決策は何かがわかったら、それに応じて答えを更新します。

于 2012-06-27T07:34:32.750 に答える