假设我有一个包含大量列的学生表。我希望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();
答案 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
因此,您可以看到订单有时很重要。