2010-06-25 48 views
1

我有SQL 2008服务器与表员工,电话和电子邮件,其中员工与电话和电子邮件(所以员工可以有很多电话号码和电子邮件)一对多关系。LINQ到SQL - 生成错误的SQL?

现在我想查询员工的所有电话和电子邮件:

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]

哪有I W仪式这样的linq查询没有分组的结果? 我知道如何进行多次左连接,但后来我需要按照EmployeeID对结果进行分组。

回答

0

你试过这样做吗?

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(); 
+0

是,我已经试过了,这是迄今为止最好的解决方案,但是在这里我需要通过EmployeeId对结果进行分组以获得与众不同的员工,因为此查询不返回不同的记录! 如果您有1名员工,有2部电话和2封电子邮件,您会在结果中获得4条记录,并需要对其进行分组。 如果您只查询手机,Linq会自动为您分组,然后您将获得2名手机的1名员工。 但谢谢你的回复。 – jojojohn 2010-06-30 17:04:22