2

我想知道我是否做类似的事情:

var results = source.Where(c => c.Name == "Whatever");

有什么方法可以在调用 Count() 或 ToList() 之前检查查询是否返回任何内容?我知道 Where() 懒惰地执行。

返回的数据集可能很大,调用上述方法非常耗时。

结果也永远不会为NULL...

谢谢你。

4

5 回答 5

6

由于您只想知道是否值得获得完整的结果集,所以这永远不值得。

这里只有两种情况:

  1. 您的查询没有结果。在这种情况下,检查有多少结果的查询将花费与实际查询完全相同的时间来执行,并返回与实际查询一样多的信息。在这种情况下,您一无所获(但也一无所获)。

  2. 您的查询至少有一个结果。在这种情况下,您需要返回并执行真正的查询。最终结果是,您花费的时间与不先检查所花费的时间一样多,但您还需要增加检查是否有结果的成本。该检查意味着对数据库的往返,这是一个不平凡的时间量。

如果您想知道查询是否包含任何项目,它是可能的。(只需使用Any扩展方法。)但是,如果您不需要知道实际项目是什么而不管结果是什么,这才是有益Any的。

同样值得注意的是,正如lazyberezovsky 在他的回答中所做的那样,您还需要考虑在调用后查询结果发生变化的竞争条件Any

于 2013-01-24T20:11:47.337 回答
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()or Any()before 获取所有数据。在其他情况下,您必须使用类似ToList().

于 2013-01-24T20:00:37.730 回答
1

当然只是使用 Any 它会告诉你是否有任何结果。

results.Any();

根据 MSDN:

此方法不返回集合的任何一个元素。相反,它确定集合是否包含任何元素。一旦可以确定结果,就停止源的枚举。

MSDN 任何

于 2013-01-24T19:54:57.323 回答
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 的复杂类类型,因此似乎没问题。

于 2013-01-24T20:27:05.177 回答
-2
var any = (source.Where(c => c.Name == "Whatever").FirstOrDefault() != null);

FirstOrDefault 将作为 SELECT TOP 1 (LinqToSql) 执行

于 2013-01-24T20:01:14.683 回答