2009-11-04 1 views
1

J'utilise Entity Framework avec SQL Server Express 2008. Lorsque vous utilisez le profileur, je vois SQL généré comme ceci:Comment puis-je faire Entity Framework produit nettoyant SQL

SELECT 
[Project1].[C1] AS [C1], 
[Project1].[EmployeeID] AS [EmployeeID], 
[Project1].[FirstName] AS [FirstName], 
[Project1].[LastName] AS [LastName], 
[Project1].[Active] AS [Active], 
[Project1].[Updated] AS [Updated], 
[Project1].[Created] AS [Created], 
[Project1].[CreatedBy] AS [CreatedBy], 
[Project1].[Modified] AS [Modified], 
[Project1].[ModifiedBy] AS [ModifiedBy] 
FROM (SELECT 
    [Extent1].[EmployeeID] AS [EmployeeID], 
    [Extent1].[FirstName] AS [FirstName], 
    [Extent1].[LastName] AS [LastName], 
    [Extent1].[Active] AS [Active], 
    [Extent1].[Updated] AS [Updated], 
    [Extent1].[Created] AS [Created], 
    [Extent1].[CreatedBy] AS [CreatedBy], 
    [Extent1].[Modified] AS [Modified], 
    [Extent1].[ModifiedBy] AS [ModifiedBy], 
    1 AS [C1] 
    FROM [dbo].[Employee] AS [Extent1] 
) AS [Project1] 
ORDER BY [Project1].[LastName] ASC 

Le fait d'avoir ce que j'appelle une sous-requête affecte les performances de SQL Server et/ou de mon application? Si je devais écrire cette requête SQL à la main, il ressemble plus à ceci:

SELECT 
[Project1].[EmployeeID] AS [EmployeeID], 
[Project1].[FirstName] AS [FirstName], 
[Project1].[LastName] AS [LastName], 
[Project1].[Active] AS [Active], 
[Project1].[Updated] AS [Updated], 
[Project1].[Created] AS [Created], 
[Project1].[CreatedBy] AS [CreatedBy], 
[Project1].[Modified] AS [Modified], 
[Project1].[ModifiedBy] AS [ModifiedBy] 
FROM [dbo].[Employee] AS [Project1] 
ORDER BY [Project1].[LastName] ASC 

Y at-il un moyen de faire ce nettoyeur? Pourquoi la sous-requête est-elle créée? Devrais-je m'en préoccuper? J'utilise LinqToEntities. Voici la fonction qui a créé le premier échantillon de SQL:

public DTO.EmployeeDTO[] GetEmployees() 
{ 
    using (KDMEntities ctx = new KDMEntities()) 
    { 
     var employees = (from e in ctx.Employees 
         orderby e.LastName 
         select new DTO.EmployeeDTO 
         { 
          EmployeeID = e.EmployeeID, 
          FirstName = e.FirstName, 
          LastName = e.LastName, 
          Active = e.Active, 
          Updated = e.Updated, 
          Created = e.Created, 
          CreatedBy = e.CreatedBy, 
          Modified = e.Modified, 
          ModifiedBy = e.ModifiedBy 
         }).ToArray(); 
     return employees; 
    } 
} 

Répondre

5

Tout d'abord, je dirais aussi longtemps que vous obtenez « assez bon » performance, il est classique compromis entre la productivité (vous n » Je dois gérer la construction de chaque bit SQL et lire manuellement SqlDataReaders etc.) et potentiellement la performance.

Mesurer, mesurer, mesurer - et voir si c'est vraiment un problème avant de sur-optimiser prématurément. Ne fais pas ça. Deuxièmement, je ne connais aucun point d'extension disponible pour vous permettre de vous connecter au processus de génération SQL dans EF. Vous avez donc le choix entre: les performances sont-elles suffisantes et puis-je obtenir utilisé pour le fait que EF pourrait générer certaines déclarations différemment que je le ferais manuellement - ou alors le laisser tomber et utiliser quelque chose d'autre. Encore une fois: c'est un compromis, car presque tout dans l'informatique - en général, c'est la performance par rapport à la productivité, et tant que la performance est «assez bonne», je ne passerais pas une minute sur l'optimisation - vos utilisateurs et les gestionnaires et les clients ne s'en soucient pas vraiment.

+1

+1 pour mesurer d'abord, puis décider. L'optimisation prématurée est un trou noir. –

+0

Je ne suis pas en désaccord avec ce que vous dites, mais cela ne répond pas à la question du PO. À mon avis, c'est un cauchemar de performance potentiel si vous n'êtes pas au courant de ce qui se passe dans les coulisses. Je viens de rencontrer exactement le même problème et je voudrais comprendre comment je peux empêcher EF de créer cette sous-requête. – DMC

Questions connexes