如果调用ToList或ToArray,为什么C#编译器允许在表达式树中使用动态操作
请注意:我知道这里讨论的主要错误消息有很多相关信息,但我找不到任何讨论我问题的帖子。 因此,请仔细阅读,然后再将其标记为副本 像往常一样,如果你能指出一个讨论我所困惑的问题的问题,我很乐意把这个问题记下来如果调用ToList或ToArray,为什么C#编译器允许在表达式树中使用动态操作,c#,lambda,expression,ienumerable,iqueryable,C#,Lambda,Expression,Ienumerable,Iqueryable,请注意:我知道这里讨论的主要错误消息有很多相关信息,但我找不到任何讨论我问题的帖子。 因此,请仔细阅读,然后再将其标记为副本 像往常一样,如果你能指出一个讨论我所困惑的问题的问题,我很乐意把这个问题记下来 我有一个方法返回一个IQueryable,如下所示 public IQueryable<dynamic> GetData(DateTime Start, DateTime End, Nullable<int> EmployeeId = null) { var
我有一个方法返回一个IQueryable,如下所示
public IQueryable<dynamic> GetData(DateTime Start, DateTime End, Nullable<int> EmployeeId = null)
{
var query = from T1 in Context.Table1
join T2 in Context.Table2
on T1.Col1 equals T2.Col1
join T3 in Context.Table3
on T2.Col1 equals T3.Col1
where T1.Col1 == EmployeeId
&& T1.Col2 >= Start
&& T1.Col2 <= End
select new
{
Value1 = T1.Col1,
Value2 = T2.Col5,
Value3 = T3.Col7
};
return query;
}
这给了我下面的编译器错误
表达式树不能包含动态操作
令人困惑的部分:
如果在调用Sum()之前添加.ToList()或.ToArray(),则不会出现此编译器错误
我知道.ToList()或.ToArray()将查询具体化(在本例中是从数据库中获取数据),并生成IEnumerable而不是IQueryable,但为什么C编译器允许我在这里的表达式中使用动态操作?
注意:C#的版本是4.0(.net4.0)在第一种情况下,您调用的是IQueryable.Sum
public static int Sum<TSource>(this IQueryable<TSource> source,
Expression<Func<TSource, int>> selector)
public static int Sum(此IQueryable源,
表达式选择器)
在第二种情况下,您调用的是IEnumerable.Sum
public static int Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource, int> selector)
public static int Sum(此IEnumerable源代码,
Func选择器)
因此,在第一种情况下,编译器尝试从lambda表达式创建表达式树,但由于您使用的是dynamic,所以无法创建表达式树。在第一种情况下,您调用的是IQueryable.Sum
public static int Sum<TSource>(this IQueryable<TSource> source,
Expression<Func<TSource, int>> selector)
public static int Sum(此IQueryable源,
表达式选择器)
在第二种情况下,您调用的是IEnumerable.Sum
public static int Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource, int> selector)
public static int Sum(此IEnumerable源代码,
Func选择器)
因此,在第一种情况下,编译器尝试从lambda表达式创建表达式树,但由于您使用的是dynamic,因此无法创建表达式树。您可能需要了解更多有关
Func
和表达式之间的区别的信息。前一种情况下没有表达式树。@IvanStoev谢谢。遗憾的是,我没有注意到两个Sum方法接受不同的参数。没有问题,伙计,这种情况经常发生:)通常避免在返回可查询项的方法中使用dynamic
和匿名类型。一个简单的结果类(又称DTO)将使您免于麻烦。您可能需要进一步了解Func
和Expression
之间的区别。前一种情况下没有表达式树。@IvanStoev谢谢。遗憾的是,我没有注意到两个Sum方法接受不同的参数。没有问题,伙计,这种情况经常发生:)通常避免在返回可查询项的方法中使用dynamic
和匿名类型。一个简单的结果类(又称DTO)将使您免于麻烦。