C# 为什么在使用静态字段中的表达式时会出现InvalidCastException?

C# 为什么在使用静态字段中的表达式时会出现InvalidCastException?,c#,.net,linq,linqkit,C#,.net,Linq,Linqkit,我刚刚开始使用EntityFramework 6.0.2,我有以下问题 为什么会这样: public static readonly Expression<Func<MyEnum, string>> ConvertToString = e => e == MyEnum.One ? "one" : e == MyEnum.Two

我刚刚开始使用EntityFramework 6.0.2,我有以下问题

为什么会这样:

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;
}
但这是:

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;
}
private静态字符串GetSomething(IQueryable things)
{
表达式ConvertToString=e=>e==MyEnum.One
“一个”
:e==MyEnum.Two
“两个”
:“零”;
var ret=事物
.AsExpandable()
.Select(c=>ConvertToString.Invoke(c.SomeEnum))
.First();
返回ret;
}

工作正常?

这是因为在表达式中您正在访问一个字段。异常告诉您正在访问一个字段

创建查询时不计算表达式。它仅在执行后执行。此时,它将需要解析字段。解决方法是首先将表达式放入局部变量:

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

    var ret = things
        .AsExpandable()
        .Select(c => expression.Invoke(c.SomeEnum))
        .First();
    return ret;
}
private静态字符串GetSomething(IQueryable things)
{
变量表达式=Program.ConvertToString;
var ret=事物
.AsExpandable()
.Select(c=>expression.Invoke(c.SomeEnum))
.First();
返回ret;
}
看到您正在使用EntityFramework时,将发生的是表达式将转换为SQL查询。但是,由于您正在访问表达式内部的类,因此它无法将其转换为SQL语句(它将如何转换?)。
当您有一个表达式实例(带有局部变量)时,您将取消此类访问,并且该表达式可以转换为SQL。

谢谢您的回答-我已经将代码更改为使用局部变量方法,但我想我问题的重点是(如果我这么说的话,我想会说得更好):为什么它不能在运行时解析该字段?这个库看起来非常聪明,可能我期望的太多了。用更多的信息编辑了我的答案谢谢你的答案和更新-我现在就知道了。让我觉得它是合理的是你可以做到:
私有静态只读表达式SomeCondition=e=>e、 SomeEnum==MyEnum.Two;
然后是
things.First(Program.SomeCondition)
但是,当然,这里的表达式没有引用类字段,整个表达式只是从字段添加到表达式树中。我仍然感到有点失望,因为我必须这样做,但无论如何,这个库就像一个礼物,我不应该抱怨。
private static string GetSomething(IQueryable<EnumTest> things)
{
    var expression = Program.ConvertToString;

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