Выполнение запроса Linq и Lambda-Expressions и определение «1 AS [C1]» в выполненном запросе - PullRequest
2 голосов
/ 20 марта 2012

У меня один и тот же запрос, написанный как в LINQ, так и в выражении лямбда-выражений:

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 генерирует код, который является более гибким, чем код с лямбда-выражениями.

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 ]

7 голосов
/ 20 марта 2012

У меня один и тот же запрос, написанный как в LINQ, так и в лямбда-выражениях.

Нет, нет. Ваше выражение запроса имеет два внутренних соединения; Ваша версия нотации вызова метода - нет. Кроме того, ваше выражение запроса создает новый объект 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
          };

Части AS в сгенерированном SQL предназначены только для того, чтобы запрос мог различать одинаковые имена столбцов, поступающие из разных таблиц или разных строк в таблицах, все в одном и том же результате.

1 голос
/ 20 марта 2012

Я почти уверен, что вы сможете написать linq-запрос на основе лямбда-выражений, который сгенерирует тот же sql, что и ваш lambda linq.Оператор соединения также может использоваться с лямбдами.Но, вероятно, это будет намного страшнее, чем не лямбда-версия.

Оператор AS - это просто псевдоним в SQL, он позволяет ссылаться на столбец или таблицу, используя имя, отличное от того, под которым оно сохранено.в таблице.Это очень похоже на именование локальных переменных в вашем коде на c #, чтобы упростить понимание происходящего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...