[英]Difference between comparing two properties and two values in Linq Where clause
Please consider the following statement: 请考虑以下声明:
var matches = person.Contacts.Where(c => c.ContactType == searchContact.ContactType).ToList();
This will filter all the records with matching ContactType of searchContact object and returns only the filtered Contacts of person. 这将过滤与searchContact对象的ContactType匹配的所有记录,并仅返回已过滤人员的Contacts。 But without ToList() method call at the end of the Where clause, it will return all the Contacts of person. 但是,如果在Where子句的末尾没有调用ToList()方法,它将返回person的所有Contacts。
Now, consider the following code segment. 现在,考虑以下代码段。
Dictionary<int, string> colors = new Dictionary<int, string>(){ {1, "red"}, {2, "blue"}, {3, "green"}, {4, "yellow"}, {5, "red"}, {6, "blue"}, {7, "red"} };
var colorSet = colors.Where(c => c.Value == "red");
This query will filter only the elements with value "red", even without calling ToList() method. 该查询将仅过滤值为“ red”的元素,即使不调用ToList()方法也是如此。
My question is why this two statements (one that compares values and one that compares properties) behave in a different way without ToList() method call? 我的问题是,为什么这两个语句(一个比较值而一个比较属性)在没有ToList()方法调用的情况下以不同的方式表现呢? Why this problem does not occur with FirstOrDefault instead of Where clause? 为什么使用FirstOrDefault而不是Where子句不会发生此问题?
I really appreciate, if anyone can explain the scenario or post some references that I can follow. 我真的很感激,如果有人可以解释这种情况或发布一些我可以遵循的参考资料。 Thanks!! 谢谢!!
You are mistaken. 你误会了。 Without calling ToList()
or another method to force immediate execution, both statements will return an IQueryable<T>
. 在不调用ToList()
或其他方法强制立即执行的情况下,两个语句都将返回IQueryable<T>
。 Until you iterate over your query variable by using a foreach
the query variable remains just that. 在使用foreach
查询变量之前,查询变量将保持不变。
This article on MSDN should explain things well: Query Execution . 有关MSDN的这篇文章应该很好地解释一下: 查询执行 。
What you are experiencing is called Deferred Query Execution . 您遇到的情况称为延迟查询执行 。
In a query that returns a sequence of values, the query variable itself never holds the query results and only stores the query commands. 在返回值序列的查询中,查询变量本身从不保存查询结果,而仅存储查询命令。 Execution of the query is deferred until the query variable is iterated over in a foreach or For Each loop. 查询的执行被推迟,直到在foreach或For Each循环中迭代查询变量为止。 This is known as deferred execution. 这称为延迟执行。
When you use ToList()
what occurs is known as Immediate Query Execution . 当您使用ToList()
,发生的事情称为即时查询执行 。
In contrast to the deferred execution of queries that produce a sequence of values, queries that return a singleton value are executed immediately. 与产生一系列值的查询的延迟执行相反,返回单值的查询将立即执行。 Some examples of singleton queries are Average, Count, First, and Max. 单例查询的一些示例是“平均值”,“计数”,“第一”和“最大值”。 These execute immediately because the query must produce a sequence to calculate the singleton result. 这些操作将立即执行,因为查询必须产生一个序列来计算单例结果。 You can also force immediate execution. 您还可以强制立即执行。 This is useful when you want to cache the results of a query. 当您要缓存查询结果时,这很有用。 To force immediate execution of a query that does not produce a singleton value, you can call the ToList method, the ToDictionary method, or the ToArray method on a query or query variable. 要强制立即执行不产生单例值的查询,可以在查询或查询变量上调用ToList方法,ToDictionary方法或ToArray方法。
These are core behaviors of LINQ. 这些是LINQ的核心行为。
But without ToList() method call at the end of the Where clause, it will return all the Contacts of person. 但是,如果在Where子句的末尾没有调用ToList()方法,它将返回person的所有Contacts。
No, without ToList
it will return a query which, when iterated, will yield all of the contacts matching the value you specified to filter on. 不,没有ToList
,它将返回一个查询,该查询在进行迭代时将产生与您指定要过滤的值匹配的所有联系人。 Calling ToList
only materializes that query into the results of that query. 调用ToList
只会将该查询具体化为该查询的结果。 Waiting a while and iterating it later, possibly using some other method of iteration such as foreach
, will only change the results if the underlying data source (in this case, a database, by the look of thigns) changes its data. 等待片刻,然后再进行迭代(可能使用其他迭代方法,例如foreach
,只有在基础数据源(在这种情况下,从外观上看,数据库)更改其数据时,才会更改结果。
As to your dictionary filter, the same thing applies. 至于字典过滤器,同样适用。 Without calling ToList
the variable represents a query to get the data when asked , not the results of that query , which is what you would get by calling ToList
. 在不调用ToList
的情况下,变量表示一个查询,用于在询问时获取数据 ,而不是查询的结果 ,这就是通过调用ToList
可以得到的结果。
The use of a property versus a field is irrelevant here. 这里,属性与字段的使用无关紧要。 Having said that , both queries are using properties, not fields. 话虽如此 ,两个查询都使用属性,而不是字段。 Even if one did use a field though, it wouldn't change a thing. 即使使用字段,也不会改变任何事情。
But without ToList() method call at the end of the Where clause, it will return all the Contacts of person. 但是,如果在Where子句的末尾没有调用ToList()方法,它将返回person的所有Contacts。
You are wrong. 你错了。 ToList
is just forces the iteration and gives you your filtered elements as a List
. ToList
只是强制迭代,并为您提供过滤后的元素作为List
。 LINQ
uses deferred execution which means until you use foreach
loop to iterate over items or use ToList
or ToArray
methods, it's not executed.So ToList
doesn't change your items. LINQ
使用延迟执行,这意味着直到您使用foreach
循环来迭代项目或使用ToList
或ToArray
方法之前,它都不会执行。因此, ToList
不会更改您的项目。 Value
is also a property (see KeyValuePair<T,K>
class), so you are performing a comparison based on property values in both query.There is no difference at all. Value
也是一个属性(请参见KeyValuePair<T,K>
类),因此您将基于两个查询中的属性值进行比较。根本没有区别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.