我想知道我是否做了类似的事情:
var results = source.Where(c => c.Name == "Whatever");
有没有办法在调用Count()或ToList()之前检查查询是否返回了什么?我知道Where()懒惰地执行。
返回的数据集可能很大,调用上述方法非常耗时。
结果永远不会为NULL ...
谢谢。
答案 0 :(得分:6)
既然你只是想知道获得完整的结果集是否值得,那就永远不值得了。
这里只有两种情况:
您的查询没有结果。在这种情况下,检查有多少结果的查询将花费与执行一样长的时间,并返回与 real 查询一样多的信息。在这种情况下,你什么也得不到(但也没有失去任何东西)。
您的查询至少有一个结果。在这种情况下,您需要返回并执行真实查询。最终的结果是你花了尽可能多的时间没有先检查,但是你还要增加检查是否有结果的费用。该检查意味着往返数据库,这是一个非常重要的时间。
如果您想知道查询是否包含任何项目可能。 (只需使用Any
扩展方法。)但是,如果您不需要知道实际项目是什么,那么它只是有益,无论Any
的结果是什么
同样值得注意的是,正如lazyberezovsky在his answer中所做的那样,您还需要考虑在您致电Any
后查询结果发生变化的竞争条件。
答案 1 :(得分:3)
知道查询是否会返回某些内容的唯一方法是执行该查询。因此,您可以获得结果或检查结果计数/存在。 但是在第二种情况下,您无法确定进一步执行查询是否会产生相同的结果。
样品:
List<int> items = new List<int>() { 1, 2, 3 };
var query = items.Where(i => i > 0);
// query is not executed at this point
var count = query.Count(); // first execution, returns 3
items.Clear();
var positiveItmes = query.ToList(); // ooop, no items here!
因此,如果您确定查询之间的数据不会更改(是吗?完全?),您可以在获取所有数据之前使用Count()
或Any()
。在其他情况下,您必须使用ToList()
。
答案 2 :(得分:1)
当然只是使用任何它会告诉你是否有任何结果。
results.Any();
根据MSDN:
此方法不返回集合的任何一个元素。相反,它确定集合是否包含任何元素。 一旦确定结果,就会停止源的枚举。
答案 3 :(得分:0)
感谢您提供有用的建议和精确度。我最终在我的通用EF存储库中实现了这个:
public bool CheckExists(string tableName, string whereField, string whereValue)
{
string query = string.Format("SELECT COUNT(*) FROM {0} WHERE {1} = {2}", tableName, whereField, whereValue);
var count = _context.ExecuteStoreQuery<int>(query).FirstOrDefault();
if (count == 0)
return false;
else
return true;
}
快得多! :)我仍在执行查询,但由于我没有要求LINQ / EF将潜在结果转换为IENumerable的复杂类类型,所以似乎没问题。
答案 4 :(得分:-2)
var any = (source.Where(c => c.Name == "Whatever").FirstOrDefault() != null);
FirstOrDefault将作为SELECT TOP 1(LinqToSql)执行