Linq vs Lambda-Expressions查询执行和执行查询中的“1 AS [C1]”修复

时间:2012-03-20 08:15:41

标签: c# sql linq lambda linq-to-entities

我有用LINQ和Lambda表达式编写的相同查询:

LINQ:

var str = (from userInfo in context.UserInfos
 join user in context.Users on userInfo.UserId equals user.UserID
 join membership in context.Memberships on userInfo.UserId equals membership.UserId
 where user.UserName == userName
 select new UserData
  {
     UserName = user.UserName,
     FirstName = userInfo.FirstName,
     LastName = userInfo.LastName,
     Email = membership.Email,
     UserId = user.UserID
 });

λ-表达式:

var str1 = context.Users.Where(p => p.UserName == userName).Select(p => new
            {
                UserName = p.UserName,
                FirstName = p.UserInfo.FirstName,
                LastName = p.UserInfo.LastName,
                Email = p.UserInfo.Membership.Email,
                UserId = p.UserID
            });

所以我查看了它们生成的代码,看起来LINQ查询生成的代码比使用Lambda-Expressions的代码更灵活。

LINQ:

SELECT 
1 AS [C1], 
[Extent2].[UserName] AS [UserName], 
[Extent1].[FirstName] AS [FirstName], 
[Extent1].[LastName] AS [LastName], 
[Extent3].[Email] AS [Email], 
[Extent2].[UserID] AS [UserID]
FROM   [dbo].[UserInfo] AS [Extent1]
INNER JOIN [dbo].[aspnet_Users] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[UserID]
INNER JOIN [dbo].[aspnet_Membership] AS [Extent3] ON [Extent1].[UserId] = [Extent3].[UserId]
WHERE [Extent2].[UserName] = @p__linq__0

λ-表达式:

SELECT 
1 AS [C1], 
[Extent1].[UserName] AS [UserName], 
[Extent3].[FirstName] AS [FirstName], 
[Extent4].[LastName] AS [LastName], 
[Extent6].[Email] AS [Email], 
[Extent1].[UserID] AS [UserID]
FROM      [dbo].[aspnet_Users] AS [Extent1]
LEFT OUTER JOIN [dbo].[UserInfo] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[UserId]
LEFT OUTER JOIN [dbo].[UserInfo] AS [Extent3] ON [Extent2].[UserId] = [Extent3].[UserId]
LEFT OUTER JOIN [dbo].[UserInfo] AS [Extent4] ON [Extent2].[UserId] = [Extent4].[UserId]
LEFT OUTER JOIN [dbo].[UserInfo] AS [Extent5] ON [Extent2].[UserId] = [Extent5].[UserId]
LEFT OUTER JOIN [dbo].[aspnet_Membership] AS [Extent6] ON [Extent5].[UserId] = [Extent6].[UserId]
WHERE [Extent1].[UserName] = @p__linq__0

所以我有两个问题:

  1. 似乎LINQ查询生成了更灵活的代码,我想它会更快。这是否意味着 join 表达式更适合在标准LINQ查询中编写?
  2. 1 AS [C1]在两个生成的代码中的含义是什么?为什么LINQ会生成该代码?

2 个答案:

答案 0 :(得分:7)

  

我使用LINQ和Lambda表达式编写相同的查询。

不,不。您的查询表达式有两个内连接;您的方法调用符号版本没有。此外,您的查询表达式在其UserData子句中构建新的select对象,而您的方法调用版本使用匿名类型。

如果要使用方法表示法编写查询表达式版本,则需要引入透明标识符 - 它会变得混乱(通常在方法调用表示法中进行连接)。您的方法调用表示法很容易表达为查询表达式:

var str = from userInfo in context.UserInfos
          where user.UserName == userName
          select new
          {
              UserName = p.UserName,
              FirstName = p.UserInfo.FirstName,
              LastName = p.UserInfo.LastName,
              Email = p.UserInfo.Membership.Email,
              UserId = p.UserID
          };

生成的SQL中的AS部分只是为了允许查询区分来自不同表或表中不同行的相同列名,所有这些都在同一结果中。

答案 1 :(得分:1)

我很确定您将能够编写基于lambda表达式的linq查询,该查询将生成与非lambda linq相同的sql。 join运算符也可以与lambdas一起使用。但它可能比非lambda版本更加丑陋。

AS运算符只是SQL中的别名,它允许您使用与表中保存的名称不同的名称来引用列或表。这很像在c#代码中命名局部变量,以便更容易理解正在发生的事情。