Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.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# 实体框架和lambda表达式树(深度空合并)_C#_Entity Framework - Fatal编程技术网

C# 实体框架和lambda表达式树(深度空合并)

C# 实体框架和lambda表达式树(深度空合并),c#,entity-framework,C#,Entity Framework,我得到了正确的可能为NullReferenceException的消息 所以我 var articles = context.Articles.Where(a => a.Id != articleId) .OrderBy(p => p.Categories.OrderBy(q => q.Name).FirstOrDefault().Name).ToList(); 这是可行的,但声明调用了两次,可能会很慢,所以我尝试 var articles = context.Articl

我得到了正确的可能为NullReferenceException的消息

所以我

var articles = context.Articles.Where(a => a.Id != articleId)
.OrderBy(p => p.Categories.OrderBy(q => q.Name).FirstOrDefault().Name).ToList();
这是可行的,但声明调用了两次,可能会很慢,所以我尝试

var  articles = context.Articles.Where(a => a.Id != articleId)
                               .OrderBy(p =>
                                   (p.Categories.OrderBy(q => q.Name).FirstOrDefault() != null
                                    ? p.Categories.OrderBy(q => q.Name).FirstOrDefault().Name
                                    : null))
                               .Skip(page * pageSize)
                                  .Take(pageSize)
                                  .ToList();
但我明白了

具有语句体的lambda表达式无法转换为 表达式树

我能做什么?即使我调用了两次
p.Categories.OrderBy(q=>q.Name).FirstOrDefault()。


我认为这可能是缓慢的。我在数据库中有200000行。

这似乎是一个重复的答案:您似乎无法使用大括号表示的代码块

我得到了正确的可能为NullReferenceException的消息

目前还不清楚是哪个系统产生了这条信息。再竖琴

无论如何,在这种情况下,如果这真的是LINQ到实体,那么警告是虚假的。 LINQ to Entities在许多情况下执行自动“深度空合并”,这就是一种情况。

在原始查询中:

var articles = context.Articles.Where(a => a.Id != articleId)
             .OrderBy(p =>
             {
                 var firstOrDefault = p.Categories.OrderBy(q => q.Name).FirstOrDefault();
                 return firstOrDefault != null ? firstOrDefault.Name : null;
             }).ToList();
…如果一篇文章没有与之关联的类别,则不会出现
NullReferenceException
。相反,对于此类文章,排序值将被视为
null
(意味着没有任何类别的文章将首先出现),这似乎正是您想要的。所以不需要你方付出额外的努力

请注意,对于其他LINQ提供程序(例如LINQ to对象),行为可能会有很大不同,而且
.FirstOrDefault().XXX
确实是一个危险的表达式


另一方面,不要过早地优化。如果您已经有了一个可行的解决方案,请对其进行基准测试。如果太慢,请调查原因——在本例中,线索在生成的SQL中。LINQ to Entities查询优化器通常比您想象的更智能。:)

您的第二个示例确实会生成更复杂的SQL查询,但该查询是否真的较慢取决于数据库。无论如何,您只需稍微更改第一个查询,它就可以在没有警告的情况下正常工作:

var articles = context.Articles
                      .Where(a => a.Id != articleId)
                      .OrderBy(p => p.Categories
                                     .OrderBy(q => q.Name)
                                     .FirstOrDefault()
                                     .Name)
                       .ToList();
查询中的问题是在调用
FirstOrDefault
之后选择
Name
,因此如果在调用
FirstOrDefault
之前投影结果,则不会产生警告,但在生成的SQL中会有额外的子选择


顺便说一句,@Ani的答案是正确的。

您是否有必要使用
lambda
?通过重新分解一些
lambda
表达式,可能更容易解决您的解决方案并使代码更具可读性。LINQ to Entities无法将自定义方法调用转换为等效的SQL。很公平-我没有意识到它使用的是实体框架。是的,这是正确的答案。Linq to entities将正确解释第一个查询。是的,resharper给我此消息。所以这个信息是不相关的。那么为什么resharper会给出这个消息呢。@senzacionale:resharper(目前)可能不够聪明,无法考虑LINQ提供程序的特性。在一般情况下,警告是正确的-在这种情况下不可能发生。如果需要,您可以使用注释禁用警告(它为您提供了执行此操作的选项)。
var articles = context.Articles
                      .Where(a => a.Id != articleId)
                      .OrderBy(p => p.Categories
                                     .OrderBy(q => q.Name)
                                     .Select(q => q.Name)
                                     .FirstOrDefault())
                      .ToList();