私は子プロパティでフィルタリングする必要があるリストを持っています。フィルタ演算子は動的で、いくつかのフィルタ/ lambdasを結合するために述語ビルダーを使用しています。簡単にするためにネストされたプロパティを持つ動的linq式ツリー
、のは、私はこのような2つのクラスを持っているとしましょう:
public class FirstClass
{
public int Id { get; set; }
public ICollection<SecondClass> MyList { get; set; }
}
public class SecondClass
{
public int ReferenceId { get; set; }
public int Value { get; set; }
}
私のフィルタは、擬似コードは次のようになるよう、オペレータのタイプと値を参照IDを使用します。
"list of FirstClass".Where(param1 =>
param1.MyList.Single(param2 =>
param2.ReferenceId == "reference id").Value "operatorType" "value")
実際のフィルタは、参照番号123で、operatorTypeは「EQ」であり、値は456
operat場合である123 eq 456
ようなもの、であろうまた、唯一の動的な式とFirstClass
にフィルタリング、例えば、魔法のように動作
Expression<Func<FirstClass, bool>> lambda =
param1 => param1.MyList.Single(param2 => param2.ReferenceId == id).Value == value;
:またはちょうどうまく平等、その後、次のような作品でしたIDにフィルタリング(私のExpressionTypeDictionaryが提供operatorType
に基づいExpressionType
を選択するための辞書です):
var parameter = Expression.Parameter(typeof(FirstClass), "param1");
Expression body = parameter;
body = Expression.Property(body, "Id");
body = Expression.MakeBinary(ExpressionTypeDictionary[operatorType], body, value);
var lambda = Expression.Lambda<Func<FirstClass, bool>>(body, new[] { parameter });
私は次のようにコンパイルするために取得することができるよ、しかし、EFコアを使用して、実際のデータにフィルタを実行すると返されますquerySourceのための例外:任意の提案が高く評価されている
var parameter = Expression.Parameter(typeof(FirstClass), "param1");
Expression<Func<FirstClass, int>> left = param1 =>
param1.MyClass.Single(param2 => param2.ReferenceId == id).Value;
var body = Expression.MakeBinary(
ExpressionTypeDictionary[operatorType],
left.Body,
Expression.Constant(value));
var lambda = Expression.Lambda<Func<FirstClass, bool>>(body, new[] { parameter });
...
theList.Where(lambda);
:)
あなたの提案は、さらに一歩私を得たが、私はバグがありだと思いますEF Core(バージョン1.0.0を使用しています)では、SQL照会で 'Expression.And'が'& 'に変換されます。代わりに 'Expression.AndAlso'を使用することで、SQL構文はうまくいき、すべてが期待通りに機能します。 –
おっと、申し訳ありません、それは 'AndAlso'である必要があります、私はいつもそれらを台無しに:) –