4

EntityFramework 6.0.2 でLinqKitを使い始めたばかりで、次の質問があります...

なぜこれを行うのですか:

public static readonly Expression<Func<MyEnum, string>> ConvertToString = e => 
        e == MyEnum.One
                    ? "one"
                    : e == MyEnum.Two
                        ? "two"
                        : "zero";

private static string GetSomethingElse(IQueryable<EnumTest> things)
{           
    var ret = things
        .AsExpandable()
        .Select(c => Program.ConvertToString.Invoke(c.SomeEnum))
        .First();
    return ret;
}

投げる:

An unhandled exception of type 'System.InvalidCastException' 
    occurred in LinqKit.dll

Additional information: Unable to cast object of type     
    'System.Linq.Expressions.FieldExpression' to type 
    'System.Linq.Expressions.LambdaExpression'.

でもこれは:

private static string GetSomething(IQueryable<EnumTest> things)
{
    Expression<Func<MyEnum, string>> ConvertToString = e => e == MyEnum.One
        ? "one"
        : e == MyEnum.Two
            ? "two"
            : "zero";

    var ret = things
        .AsExpandable()
        .Select(c => ConvertToString.Invoke(c.SomeEnum))
        .First();
    return ret;
}

正常に動作します?

4

1 に答える 1

4

これは、式内で Field にアクセスしているためです。例外は、フィールドにアクセスしていることを示しています。

クエリを作成するとき、式は評価されません。一度実行すると実行されます。その時点で、フィールドを解決する必要があります。回避策は、最初に式をローカル変数に取得することです。

private static string GetSomething(IQueryable<EnumTest> things)
{
    var expression = Program.ConvertToString;

    var ret = things
        .AsExpandable()
        .Select(c => expression.Invoke(c.SomeEnum))
        .First();
    return ret;
}

これを EntityFramework で使用していると、式が SQL クエリに変換されます。ただし、式内のクラスにアクセスしているため、これを SQL ステートメントに変換することはできません (どのように行うのでしょうか?)。式のインスタンス (ローカル変数を使用) がある場合、このクラスへのアクセスが排除され、その式を SQL に変換できます。

于 2014-03-06T12:17:57.193 に答える