Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq如何正确使用where_C#_Linq - Fatal编程技术网

C# Linq如何正确使用where

C# Linq如何正确使用where,c#,linq,C#,Linq,这两个查询之间有什么区别 它们不一样吗?哪一个更快?在where之后使用where会有问题吗?在where之后编写where使我的代码可读。我做错了吗 第一个问题: Model= (model.Where(p => p.Date.Year == yilim) .Where(p => p.Id== 2 || p.Id== 3) .OrderBy(m => m.Date.Month

这两个查询之间有什么区别

它们不一样吗?哪一个更快?在where之后使用where会有问题吗?在where之后编写where使我的代码可读。我做错了吗

第一个问题:

   Model= (model.Where(p => p.Date.Year == yilim)
                        .Where(p => p.Id== 2 || p.Id== 3)
                        .OrderBy(m => m.Date.Month))
                        .ToList();
   Model= (model.Where(p => p.Date.Year == yilim)
                .Where(p => p.Id== 2 || p.Id== 3)
                .OrderBy(m => m.Date.Month))
                .ToList();
第二个问题:

  Model= (model.Where(p => p.Date.Year == yilim && (p.Id== 2 || p.Id== 3))
                            .OrderBy(m => m.Date.Month))
                            .ToList();
  Model= (model.Where(p => p.Date.Year == yilim 
                           && (p.Id== 2 || p.Id== 3))
               .OrderBy(m => m.Date.Month))
               .ToList();

不同之处在于,在第一个查询中,第一个Where将应用于名为model的序列,而在生成的序列中,将应用第二个Where方法。而在第二个查询中,Where方法应用于名为model的序列。也就是说,第二个查询比第一个查询更有效,因为您只运行了一次模型序列

然而,声明第二步将是更有效的理论步骤。我不认为在实践中你会得到任何显著的,甚至可以测量的差异。

没有功能上的差异,因为菊花链
,其中
调用是一个逻辑
操作,而你目前正在
将这两个独立的条件组合在一起

但是,在消除编译器优化条件检查(如短路)的能力和第二个
中所需的额外枚举数方面,它的效率可能会稍低,而不仅仅是一个枚举数。(很抱歉,这部分内容只适用于Linq to Objects。)

如果您的代码要
条件,则只有第二个查询将提供您想要的:

Model= (model.Where(p => p.Date.Year == yilim || p.Id== 2 || p.Id== 3)
                          .OrderBy(m => m.Date.Month))
                          .ToList();

// Cannot express the above query in simple daisy-chained Where calls.

如果
中的逻辑变得难以读取,请尝试“无注释编码”,并将条件填充到具有非常可读名称的方法中,然后您可以执行
。其中(x=>客户名称有效(x))
,或将其分组的方法
。其中(客户名称有效)
(如果可以)。这也有助于调试,因为在方法中放置断点比在lambda中放置断点要简单一些。

您不太可能注意到两者之间有任何显著的性能差异。调用
Where()
两次确实会增加一些开销:您创建了一个额外的中间对象,当然在枚举过程中还有额外的方法调用要处理

但在大多数代码中,这些差异并不明显。如果您发现通过将筛选器拆分为对
Where()
的两个单独调用,代码更易于阅读和维护,那么这是更好的方法


至少,也就是说,直到你真的遇到性能问题。然后你可以回去重新审视这是否是你的问题的一部分,是否值得改变。

其他人的答案非常清楚,但我有一个不同的建议。为什么不通过调试来检查生成的SQL查询呢。你会看到他们之间是否有区别。要获取系统生成和运行的实际SQL查询,您可以编写以下代码:

using (EntityConnection con = new EntityConnection("Name = testEntities"))
{
    con.Open();

    using (testEntities db = new testEntities())
    {
        int yilim = 2013;

        IQueryable<Model> models = (db.Model.Where(p => p.Date.Year == yilim)
                                            .Where(p => p.ID == 2 || p.ID == 3)
                                            .OrderBy(m => m.Date.Month))
                                            .AsQueryable();

        string modelsQuery = ((System.Data.Objects.ObjectQuery)models).ToTraceString();

        IQueryable<Model> models2 = (db.Model.Where(p => p.Date.Year == yilim && 
                                                        (p.ID == 2 || p.ID == 3))
                                             .OrderBy(m => m.Date.Month))
                                             .AsQueryable();

        string modelsQuery2 = ((System.Data.Objects.ObjectQuery)models2).ToTraceString();

        System.IO.File.WriteAllText(@"C:\Users\username\Desktop\queries.txt", 
            "Query 1:\r\n" + modelsQuery + "\r\n" + 
            "Query 2:\r\n" + modelsQuery2);

    }
它们是一样的。因此,性能上的差异在这里是不可预料的

在where之后编写where使我的代码可读。我做错了吗

其他人对性能/实际编译的好处发表了评论,我只是建议代码的可读性(这是一种宗教性质,所以请谨慎对待)

重新格式化的第一个查询:

   Model= (model.Where(p => p.Date.Year == yilim)
                        .Where(p => p.Id== 2 || p.Id== 3)
                        .OrderBy(m => m.Date.Month))
                        .ToList();
   Model= (model.Where(p => p.Date.Year == yilim)
                .Where(p => p.Id== 2 || p.Id== 3)
                .OrderBy(m => m.Date.Month))
                .ToList();
我的偏好是将方法与它们应用到的类对齐。多维语句可能如下所示:

   Model= (model.Where(p => p.Date.Where(d => d.Year == 2014)
                                  .Where(d => d.Month == 11))
                .Where(p => p.Id== 2 || p.Id== 3)
                .OrderBy(m => m.Date.Month))
                .ToList();
重新格式化的第二个查询:

  Model= (model.Where(p => p.Date.Year == yilim && (p.Id== 2 || p.Id== 3))
                            .OrderBy(m => m.Date.Month))
                            .ToList();
  Model= (model.Where(p => p.Date.Year == yilim 
                           && (p.Id== 2 || p.Id== 3))
               .OrderBy(m => m.Date.Month))
               .ToList();
为了if-like运算符的可读性,我选择将所有OR保持为内联,将所有and保持在单独的行上

 Model = model.Where(m => (m.Name == "jon" || m.Name == "joe")
                          && (m.Color == "red" || m.Color == "blue"));
最后,我通常将lambda表达式参数缩短为与变量的第一个字母匹配的字母

因此:

变成:

   Model= (model.Where(m => m.Date.Year == yilim)
对于更复杂的查询,我还使用了:

   query = persons.Where(person => person == ...
                  .Where(person => person.Friends.Where(friend => 

有时,如果不阅读整个表达式树的内容,一个字母就很难与表达式联系起来。

哇,经过这么多的经验,我现在才开始学习。在这些表达式中使用具有可读名称的函数是一种天才。@Ishathat很好,它让我早上好起来,做得很好!:-)