Linq到实体中的OrderBy,Select和Where子句的顺序是否重要

时间:2016-09-08 15:57:53

标签: c# entity-framework linq

假设我有一个包含大量列的学生表。我希望EF相当于

SELECT id,lastname,firstname 
FROM students 
WHERE coursename='Eurasian Nomads'
ORDER BY lastname,firstname

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

public class StudentView{
    public int ID{get;set;}
    public string LastName{get;set;}
    public string FirstName{get;set;}
}

这个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();

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

例如,这似乎也有效:

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();

1 个答案:

答案 0 :(得分:4)

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

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

但有时订单会影响生成的sql。

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

System.NotSupportedException: The specified type member 'CourseName' is not supported in LINQ to Entities.

这里的关键是您尝试通过视图模型(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

因此,您可以看到订单有时很重要。