子プロパティでフィルタリングする必要があるリストがあります。フィルター演算子は動的であり、複数のフィルター/ラムダを組み合わせるために述語ビルダーを使用しています。
簡単にするために、次のような 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 eq 456になり、参照 ID は 123、operatorType は「eq」、値は 456 です。
演算子が等しい場合は、次のようにするとうまくいきます。
Expression<Func<FirstClass, bool>> lambda =
param1 => param1.MyList.Single(param2 => param2.ReferenceId == id).Value == value;
また、FirstClass動的な式でのみフィルタリングすることは、魅力のように機能します。たとえば、Id でフィルタリングします (私の ExpressionTypeDictionary はExpressionType、提供された に基づいてを選択するための辞書ですoperatorType)。
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 Core を使用して実際のデータに対してフィルターを実行すると、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);
どんな提案でも大歓迎です:)