2010-06-25 8 views
1

J'ai un serveur SQL 2008 avec des tables Employee, Phone et Email où Employee est dans une relation un-à-plusieurs avec le téléphone et l'email (ainsi l'employé peut avoir beaucoup de numéros de téléphone et d'email).Linq à sql - génère un mauvais sql?

Maintenant, je veux interroger employé avec tous les téléphones et les e-mails:

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

Mais LINQ traduit sql très laid, il fait se joindre à gauche avec table de téléphone, mais il interroge chaque e-mails des employés dans la requête séparée comme :

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

Ce que je dois est sql simple:

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]

Comment puis-je w rite une telle requête linq sans grouper les résultats? Je sais comment faire plusieurs jointures à gauche, mais j'ai besoin de regrouper les résultats par EmployeeID.

Répondre

0

Avez-vous essayé de le faire comme ça?

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

Qu'est-ce que vous avez besoin est LoadWith de travailler avec de multiples 1 à de nombreuses relations, mais cela ne fonctionne pas -

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

à travers des cerceaux devrait Saut travailler -

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

Oui , J'ai essayé ceci, et c'est jusqu'ici la meilleure solution MAIS ici j'ai besoin de grouper des résultats par EmployeeId pour obtenir des employés distincts, parce que cette requête ne renvoie pas des dossiers distincts! Si vous avez 1 employé avec 2 téléphones et 2 e-mails, vous obtenez 4 enregistrements dans les résultats et vous devez les regrouper. Si vous interrogez uniquement des téléphones, Linq le regroupe automatiquement pour vous et vous obtenez 1 employé avec 2 téléphones. Mais merci de répondre. – jojojohn