简化实体框架查询

时间:2016-06-29 14:53:03

标签: c# entity-framework linq

我有一个简单的linq查询,它通过creteria对结果进行排序。

var vehicles = context.Vehicles
    .AsNoTracking()
    .Where(v => v.CreatedAt >= DbFunctions.AddDays(DateTime.UtcNow, -10))
    .ToList();

但实体框架将这个简单的查询转换为

SELECT 
CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN '0X' WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN '0X0X' WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN '0X1X' ELSE '0X2X' END AS [C1], 
[Extent1].[Id] AS [Id], 
[Extent1].[CreatedAt] AS [CreatedAt], 
[Extent1].[Name] AS [Name], 
CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS bit) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN [Project1].[HasCycleCar] WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN CAST(NULL AS bit) END AS [C2], 
CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS int) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN CAST(NULL AS int) WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN [Project3].[Seats] END AS [C3], 
CASE WHEN (( NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND ( NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND ( NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS int) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN CAST(NULL AS int) WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN CAST(NULL AS int) ELSE [Project2].[Capacity] END AS [C4]
FROM    [dbo].[Vehicles] AS [Extent1]
LEFT OUTER JOIN  (SELECT 
    [Extent2].[Id] AS [Id], 
    [Extent2].[HasCycleCar] AS [HasCycleCar], 
    cast(1 as bit) AS [C1]
    FROM [dbo].[Motorcycles] AS [Extent2] ) AS [Project1] ON [Extent1].[Id] = [Project1].[Id]
LEFT OUTER JOIN  (SELECT 
    [Extent3].[Id] AS [Id], 
    [Extent3].[Capacity] AS [Capacity], 
    cast(1 as bit) AS [C1]
    FROM [dbo].[Trucks] AS [Extent3] ) AS [Project2] ON [Extent1].[Id] = [Project2].[Id]
LEFT OUTER JOIN  (SELECT 
    [Extent4].[Id] AS [Id], 
    [Extent4].[Seats] AS [Seats], 
    cast(1 as bit) AS [C1]
    FROM [dbo].[PassengerCars] AS [Extent4] ) AS [Project3] ON [Extent1].[Id] = [Project3].[Id]
WHERE [Extent1].[CreatedAt] >= (DATEADD (day, -10, SysUtcDateTime()))

来了我只需要基本信息,但EF读取所有内容,更多内容是使用繁琐的查询。我知道EF需要遵守多态行为并返回一个创建它的类型的对象。

但是,我怎么能不知道他没有读过不必要的东西?

1 个答案:

答案 0 :(得分:1)

如果您只想要实体类型属性的子集,则可以在查询中包含投影(对于匿名或命名类型):

var results = from v in context.Vehicles
              …
              select new VechicleSubSet {
                Id = v.Id,
                Name = v.Name
              };

枚举results(触发对数据库的查询)时,将仅选择NameId(如果在查询的其他位置使用,则可能会引用其他列)。

注意:在您的SQL中,您似乎在对象表映射中配置了类似Table per Class的内容:因此EF尝试返回该映射中的所有数据,而不仅仅是从单个表中返回。

相关问题