1

次のラムダ式があります

    var expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Now.AddHours(2))

expr.Body.ToString() を呼び出すと、文字列内のランタイム値を含む式本体を取得したいのですが、次の文字列が返されます。

    {((a.Name == "Alex") AndAlso (a.DateCreated < DateTime.Now.AddHours(2)))}

明確にするために、DateTime.Now.AddHours(2)の値を取得することを期待していました。私はここ数晩、猛烈にウェブを検索していましたが、結果はありませんでした. これは、何を検索すればよいかわからない私のせいかもしれません。皆さんが助けてくれることを願っています:)

4

2 に答える 2

2

DateTime 呼び出しをラムダの外に移動する必要があります。

DateTime endDate = DateTime.Now.AddHours(2);
Expression<Func<YourClass, bool>> expr = a => (a.Name == "Alex" && a.DateCreated < endDate);

それでも、値ではなく式でクロージャを表示します。

特定の日付を出力値として取得するには、次のような定数が必要です。

Expression<Func<YourClass, bool>> expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Parse("10/2/2012"));

これによりDateTime.Parse呼び出しが表示されますが、少なくとも値は表示されます (式の定数であるため)。

式を作成すると、DateTimeプロパティとメソッド (NowおよびAddHours) が式自体の一部になります。これは、閉じた変数でも発生します。式には、完全なラムダを構築するために必要なすべてのステートメントを含める必要がありDateTime.Now.AddHours(2)ます。

これは仕様によるものです。たとえば、 AddHours は Canonical Functions の 1 つであるDateTime.Now.AddHours()ため、これを Entity Framework クエリに変換する場合は、サーバー上で解決する必要があります。これを定数で置き換えた場合、期待どおりに動作しません。

于 2012-08-15T16:55:14.710 に答える
0

以下のコードは機能しますが、本当に使用するかどうかはわかりません。

Expression<Func<A,bool>> expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Now.AddHours(2));

var expr1 = expr.Body as BinaryExpression;
var expr2 = expr1.Right as BinaryExpression; //a.DateCreated < DateTime.Now.AddHours(2)
var expr3 = expr2.Right as MethodCallExpression; //DateTime.Now.AddHours(2)

var obj = expr3.Object as MemberExpression; //DateTime.Now
var pi = obj.Member as PropertyInfo;
var dt = pi.GetValue(null); //Call DateTime.Now


var arg = expr3.Arguments[0] as ConstantExpression;
var result = expr3.Method.Invoke(dt, new object[] { arg.Value }); //Call AddHours

-

public class A
{
    public string Name { set; get; }
    public DateTime DateCreated { set; get; }
}
于 2012-08-15T17:35:01.383 に答える