为什么c#编译器允许在调用ToList或ToArray时在表达式树中使用动态操作?
本文关键字:表达式 操作 动态 ToArray 编译器 调用 ToList 为什么 | 更新日期: 2023-09-27 18:02:56
请注意:我知道这里讨论的主要错误消息有许多相关,但我找不到任何讨论我问题的帖子。
因此,在将其标记为重复之前,请通读一遍。
和往常一样,如果你能指出一个问题来讨论我所困惑的问题,我很乐意把这个问题记下来。
我有一个方法返回如下的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;
}
请注意,由于表的敏感性,我不得不删除表和列名。
问题:
我想从另一个类中得到Value3的和
private float getTargetScore()
{
return GetData().Sum(rec => Convert.ToSingle(rec.Value3));
}
这给了我下面的编译错误。
表达式树不能包含动态操作
令人困惑的部分:
如果在调用Sum()之前添加。tolist()或。toarray(),则不会得到此编译器错误
private float getTargetScore()
{
return GetData().ToArray().Sum(rec => Convert.ToSingle(rec.Value3));
}
我理解。tolist()或。toarray()物化查询(在这种情况下从db中带来数据)并导致IEnumerable<>而不是IQueryable<> ,但为什么c#编译器允许我在这里使用表达式中的动态操作?
注意:c#的版本是4.0。Net 4.0)
在第一种情况下,你正在调用IQueryable。和
public static int Sum<TSource>(this IQueryable<TSource> source,
Expression<Func<TSource, int>> selector)
在第二种情况下,调用IEnumerable。和
public static int Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource, int> selector)
所以在第一种情况下,编译器试图创建一个表达式树从lambda表达式,是无法做到的,因为你使用动态