实体框架性能连接与导航属性

puk*_*uko 5 c# entity-framework

我试图理解为什么加入我的情况比使用导航属性的语句更快.我有两个问题.

首先是导航属性:

          var result = (from users in context.MetricBloodPreasure
                orderby users.User.LastName, users.User.FirstName
                select new
                {
                    UserName = users.User.LastName + ", " + users.User.FirstName,
                    Date = users.DateOfValue,
                }).ToList();
Run Code Online (Sandbox Code Playgroud)

Generatet sql:

SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[C2] AS [C2], 
    [Project1].[DateOfValue] AS [DateOfValue]
    FROM ( SELECT 
        [Extent1].[DateOfValue] AS [DateOfValue], 
        [Extent2].[FirstName] AS [FirstName], 
        [Extent2].[LastName] AS [LastName], 
        1 AS [C1], 
        CASE WHEN ([Extent2].[LastName] IS NULL) THEN N'' ELSE [Extent2].[LastName] END + N', ' + CASE WHEN ([Extent2].[FirstName] IS NULL) THEN N'' ELSE [Extent2].[FirstName] END AS [C2]
        FROM  [dbo].[MetricBloodPreasure] AS [Extent1]
        INNER JOIN [dbo].[User] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[Id]
    )  AS [Project1]
    ORDER BY [Project1].[LastName] ASC, [Project1].[FirstName] ASC
Run Code Online (Sandbox Code Playgroud)

第二次加入:

var result1 = (from u in context.User
                orderby u.LastName, u.FirstName
                join us in context.MetricBloodPreasure
                    on u.Id equals us.UserId into users
                from s in users
                select new
                {
                    UserName = s.User.LastName + ", " + s.User.FirstName,
                    Date = s.DateOfValue,
                }).ToList();
Run Code Online (Sandbox Code Playgroud)

生成的sql:

SELECT 
    1 AS [C1], 
    CASE WHEN ([Extent1].[LastName] IS NULL) THEN N'' ELSE [Extent1].[LastName] END + N', ' + CASE WHEN ([Extent1].[FirstName] IS NULL) THEN N'' ELSE [Extent1].[FirstName] END AS [C2], 
    [Extent2].[DateOfValue] AS [DateOfValue]
    FROM  [dbo].[User] AS [Extent1]
    INNER JOIN [dbo].[MetricBloodPreasure] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[UserId]) AND ([Extent2].[UserId] = [Extent1].[Id])
Run Code Online (Sandbox Code Playgroud)

在运行第一个查询之前,调用var user = context.User.FirstOrDefault();因为我认为打开与数据库的连接需要一些时间.

结果:导航属性查询:00:00:00.6719646加入查询:00:00:00.4941169

看看结果似乎Linq查询使用连接而不是导航属性更快.是真的还是我做错了什么?

Jef*_*ing 2

为了更好地了解它正在做什么,您应该获取原始 SQL,并且可以自己检查执行计划。

为此,您可以使用 SQL Profiler 查看正在运行的查询,也可以在运行查询之前通过执行以下操作来记录 SQL 查询本身:

context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
Run Code Online (Sandbox Code Playgroud)

另外,像每次运行一次一样进行简单的基准测试也不一定可靠。您需要多次运行它并取平均值。您还应该以相反的顺序运行它们,看看这是否也会改变情况。