Linq-to-entities中的OrderBy,Select和Where子句的顺序是否重要

Mat*_*hew 6 c# linq entity-framework

假设我有一张包含大量列的学生表.我想要相当于EF

SELECT id,lastname,firstname 
FROM students 
WHERE coursename='Eurasian Nomads'
ORDER BY lastname,firstname
Run Code Online (Sandbox Code Playgroud)

我只想要完整Student模型的一个子集,所以我制作了一个视图模型

public class StudentView{
    public int ID{get;set;}
    public string LastName{get;set;}
    public string FirstName{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

这个EF代码似乎工作:

List<StudentView> students=context.Students
.Where(s=>s.CourseName=="Eurasian Nomads")
.OrderBy(s=>s.LastName)
.ThenBy(s=>s.FirstName)
.Select(s=>new StudentView(){ID=s.ID,LastName=s.LastName,FirstName=s.FirstName})
.ToList();
Run Code Online (Sandbox Code Playgroud)

但我的问题是这些条款的顺序是否重要,如果是这样,我应遵循哪种规则以获得最佳表现?

例如,这似乎也有效:

List<StudentView> students=context.Students
.Select(s=>new StudentView(){ID=s.ID,LastName=s.LastName,FirstName=s.FirstName})
.OrderBy(s=>s.LastName)
.ThenBy(s=>s.FirstName)
.Where(s=>s.CourseName=="Eurasian Nomads")
.ToList();
Run Code Online (Sandbox Code Playgroud)

Kar*_*ayo 4

在大多数情况下,在对服务器执行查询之前创建查询的顺序并不相关。

实际上,优点之一是能够通过连接 where、order by 和其他子句来逐步创建查询。

但有时顺序会影响生成的sql。

获取您提供的样品。它们都编译正确,但第二个实际上并未执行。如果您尝试针对 EF 数据库运行此查询,您将收到NotSupportedException

System.NotSupportedException: The specified type member 'CourseName' is not supported in LINQ to Entities.
Run Code Online (Sandbox Code Playgroud)

这里的关键是您尝试通过视图模型 (StudentView) 中的 CourseName 属性而不是实体的属性来过滤查询。所以你会得到这个错误。

在第一个查询的情况下,它正确生成以下 SQL:

SELECT
    [Extent1].[ID] AS [ID],
    [Extent1].[LastName] AS [LastName],
    [Extent1].[FirstName] AS [FirstName]
    FROM [dbo].[Students] AS [Extent1]
    WHERE N'Eurasian Nomads' = [Extent1].[CourseName]
    ORDER BY [Extent1].[LastName] ASC, [Extent1].[FirstName] ASC
Run Code Online (Sandbox Code Playgroud)

因此,正如您所看到的,有时顺序很重要。

  • 这是一个很好的解释。我认为值得补充的是,“NotSupportedException”是因为“Select”将查询转换为“StudentView”查询,而不是“Student”查询,并且“StudentView”不包含“CourseName”的属性。 (2认同)
  • 确实@Max。这就是我说的“这里的关键是您试图通过视图模型中的 CourseName 属性过滤查询”时的意思,但我认为您的澄清当然是有效的。谢谢。 (2认同)