[英]Why does C# compiler allow use of a dynamic operation in expression tree if ToList or ToArray is called
Please note: I am aware that there are many related to the main error message discussed here but I could not find any post that discusses my question. 请注意:我知道这里讨论了许多与主要错误消息相关的信息,但是我找不到任何讨论我的问题的帖子。
Therefore, please be kind to read to the end before marking this down as a duplicate. 因此,在将此标记为重复项之前,请务必仔细阅读。
As always I am happy to take the question down if you could point to a question that discusses the issue I am confused about. 与往常一样,如果您能指出一个讨论我困惑的问题的问题,我很乐意回答这个问题。
I have a method that returns a IQueryable like below 我有一个返回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;
}
Please note that I had to remove table and column names due to sensitive nature of the tables. 请注意,由于表的敏感性,我不得不删除表名和列名。
The problem: 问题:
I want to get the sum of Value3 so from a different class. 我想从另一个类中获取Value3的总和。
private float getTargetScore()
{
return GetData().Sum(rec => Convert.ToSingle(rec.Value3));
}
This gives me below compiler error. 这给了我下面的编译器错误。
An expression tree may not contain a dynamic operation
表达式树可能不包含动态操作
The confusing part: 令人困惑的部分:
I dont get this compiler error if I add .ToList() or .ToArray() before calling Sum() 如果在调用Sum()之前添加.ToList()或.ToArray(),则不会出现此编译器错误
private float getTargetScore()
{
return GetData().ToArray().Sum(rec => Convert.ToSingle(rec.Value3));
}
I understand that .ToList() or .ToArray() materialises the query (brings data from the db in this case) and results in an IEnumerable<> rather than IQueryable<> but why does the C# compiler allow me to use a dynamic operation in an expression here? 我知道.ToList()或.ToArray()实现查询(在这种情况下从数据库中获取数据)并导致IEnumerable <>而不是IQueryable <>, 但是为什么C#编译器允许我使用动态操作在这里表达吗?
Note: Version of C# is 4.0 (.Net 4.0) 注意:C#的版本为4.0(.Net 4.0)
In the first case you are calling IQueryable.Sum 在第一种情况下,您正在调用IQueryable.Sum
public static int Sum<TSource>(this IQueryable<TSource> source,
Expression<Func<TSource, int>> selector)
In the second case you are calling IEnumerable.Sum 在第二种情况下,您正在调用IEnumerable.Sum
public static int Sum<TSource>(this IEnumerable<TSource> source,
Func<TSource, int> selector)
So in first case compiler tries to create an expression tree from lambda expression and is unable to do it since you are using dynamic. 因此,在第一种情况下,编译器尝试从lambda表达式创建表达式树 ,但由于使用动态,因此无法做到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.