私は、私たちのこの巨大なプロジェクトのために、より精巧なフィルタリング システムを作成している最中です。主な述語の 1 つは、文字列パラメーターを介して比較を渡すことができることです。これは次の形式で表されます: ">50" または "5-10" または "<123.2"
私が持っているもの(説明する例として)
ビューモデル:
TotalCost (string) (value: "<50")
Required (string) (value: "5-10")
EF モデル:
TotalCost (double)
Required(double)
使いたい表現:
model => model.Where(field => field.TotalCost.Compare(viewModel.TotalCost) && field.Required.Compare(viewModel.Required));
受け取りたい表現:
model => model.Where(field => field.TotalCost < 50 && field.Required > 5 && field.Required < 10);
またはそれに似た何か
しかし...どこから始めればよいかわかりません。まで絞ってきました
public static Expression Compare<T>(this Expression<Func<T, bool>> value, string compare)
正確ではないかもしれませんが、これが私が持っているすべてです。比較ビルダーは問題ではありません。それは簡単なことです。難しい部分は、実際に式を返すことです。式を関数値として返そうとしたことはありません。したがって、基本的に保持する必要があるのは、フィールドと比較式を返すことです。
何か助けはありますか?:バツ
アップデート:
悲しいかな、これは私の問題を解決しません。過去23時間起きていたせいかもしれませんが、拡張メソッドにする方法については少しも手がかりがありません. 私が言ったように、私が欲しいのは...基本的に書く方法です:
var ex = new ExTest();
var items = ex.Repo.Items.Where(x => x.Cost.Compare("<50"));
私がその関数を形作った方法(おそらく完全に間違っている)は
public static Expression<Func<decimal, bool>> Compare(string arg)
{
if (arg.Contains("<"))
return d => d < int.Parse(arg);
return d => d > int.Parse(arg);
}
そもそも比較する「this -something- value」がなく、式の入力を取得できるようにする方法をまだ理解できていません... ReSharperに関しては、変換することを提案しています代わりにブール値に...
今のところ、頭の中はフワフワです...
更新 2:
コンソール アプリケーションのメモリ リポジトリで動作するコードを作成する方法を見つけました。私はまだEntity Frameworkで試していません。
public static bool Compare(this double val, string arg)
{
var arg2 = arg.Replace("<", "").Replace(">", "");
if (arg.Contains("<"))
return val < double.Parse(arg2);
return val > double.Parse(arg2);
}
しかし、私はそれが私が求めているものであることを非常に疑っています
更新 3:
そうです、座ってラムダ式をもう一度調べた後、最後の回答の前に、次のようなものを思いつきました。「Compare()」の正確な要件を満たしていませんが、「オーバーロードっぽい」ですどこでメソッド:
public static IQueryable<T> WhereExpression<T>(this IQueryable<T> queryable, Expression<Func<T, double>> predicate, string arg)
{
var lambda =
Expression.Lambda<Func<T, bool>>(Expression.LessThan(predicate.Body, Expression.Constant(double.Parse(50.ToString()))));
return queryable.Where(lambda);
}
ただし、私の目には、すべてが論理的に見えますが、次の実行時例外が発生します。
System.ArgumentException was unhandled
Message=Incorrect number of parameters supplied for lambda declaration
Source=System.Core
StackTrace:
at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters)
これは明らかに犯人の行です:
var lambda =
Expression.Lambda<Func<T, bool>>(Expression.LessThan(predicate.Body, Expression.Constant(double.Parse(50.ToString()))));
私は解決策に非常に近いです。そのエラーを解決できれば、EF はそれを SQL に変換できるはずです。そうでなければ... まあ、最後の応答はおそらく行くでしょう。