Linq to sql - генерирует неправильный sql? - PullRequest
1 голос
/ 25 июня 2010

У меня есть сервер SQL 2008 с таблицами Employee, Phone и Email, где Employee имеет отношение «один ко многим» с Phone и Email (таким образом, сотрудник может иметь много телефонных номеров и адресов электронной почты).

Теперь яЯ хочу запросить сотрудника со всеми телефонами и электронными письмами:

var query = (from e in db.Employee
             select new EmployeeDTO
             {
                 Id = e.Id,
                 Name = e.Name,
                 Phones = e.Phones,
                 Emails = e.Emails
             }).ToList();

Но linq переводит его в очень уродливый sql, делает левое соединение с таблицей телефонов, но затем запрашивает электронные письма каждого сотрудника в отдельном запросе, например:

SELECT [t0].[EmployeeID], [t0].[Name], [t1].[Phone] (
    SELECT COUNT(*)
    FROM [dbo].[Phone] AS [t2]
    WHERE [t2].[EmployeeID] = [t0].[EmployeeID]
    ) AS [value]
FROM [dbo].[Employee] AS [t0]
LEFT OUTER JOIN [dbo].[Phone] AS [t1] ON [t1].[EmployeeID] = [t0].[EmployeeID]
ORDER BY [t0].[EmployeeID], [t1].[PhoneID]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.4926

SELECT [t0].[EmailID], [t0].[Email]
FROM [dbo].[Email] AS [t0]
WHERE [t0].[EmployeeID] = @x1
-- @x1: Input UniqueIdentifier (Size = 0; Prec = 0; Scale = 0) [1ed2e9a0-ca4b-4912-8f8e-000ed8d0b2af]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.4926

SELECT [t0].[EmailID], [t0].[Email]
FROM [dbo].[Email] AS [t0]
WHERE [t0].[EmployeeID]= @x1
-- @x1: Input UniqueIdentifier (Size = 0; Prec = 0; Scale = 0) [2203192b-05ef-4b59-b4b4-0010e26a8119]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.4926

Что мне нужно, это простой sql:

SELECT [t0].[EmployeeID], [t0].[Name], [t1].[Phone], [t2].[Email]
FROM [dbo].[Employee] AS [t0]
LEFT OUTER JOIN [dbo].[Phone] AS [t1] ON [t1].[EmployeeID] = [t0].[EmployeeID]
LEFT OUTER JOIN [dbo].[Email] AS [t2] ON [t2].[EmployeeID] = [t0].[EmployeeID]

Как я могу написать такой запрос linq без группировки результатов?Я знаю, как сделать несколько левых соединений, но мне нужно сгруппировать результаты по EmployeeID.

1 Ответ

0 голосов
/ 30 июня 2010

Вы пытались сделать это так?

var query = (from e in db.Employee
    join p in db.Phones on e.EmployeeID equals p.EmployeeID into tmpPhones
    from phones in tmpPhones.DefaultIfEmpty()
    join m in db.Emails on e.EmployeeID equals m.EmployeeID into tmpEmails
    from emails in tmpEmails.DefaultIfEmpty()

             select new EmployeeDTO
             {
                 Id = e.Id,
                 Name = e.Name,
                 Phones = phones,
                 Emails = emails
             }).ToList();

Что вам нужно, это LoadWith для работы с несколькими отношениями 1 ко многим, но это не работает -

http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/a68744f6-e1f3-4d28-82eb-87b8187ec0a8/

Прыжки через обручи должны работать -

 var query = (from e in db.Employee
        join p in db.Phones on e.EmployeeID equals p.EmployeeID into tmpPhones
        from phones in tmpPhones.DefaultIfEmpty()
        join m in db.Emails on e.EmployeeID equals m.EmployeeID into tmpEmails
        from emails in tmpEmails.DefaultIfEmpty()
        group e by e into eGrp

                 select new EmployeeDTO
                 {
                     Id = eGrp.Key.Id,
                     Name = eGrp.Key.Name,
                     Phones = eGrp.Select(x => x.Phones),
                     Emails = eGrp.Select(x => x.Emails)
                 }).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...