2009-06-30 10 views
2

J'ai exécuté une trace sur certaines des requêtes générées par Linq et elles semblent très peu optimisées et maladroites.Linq To Entities Générer de grandes requêtes

Je sais que vous ne connaissez pas ma structure de données, mais est tere quoi que ce soit immidiatly mal à la requête LINQ suivante

IQueryable<Tasks> tl = db.Tasks 
           .Include("Catagories") 
           .Include("Projects") 
           .Include("TaskStatuses") 
           .Include("AssignedTo") 
           .Where 
            (t => (t.TaskStatuses.TaskStatusId.Equals(currentStatus) | currentStatus == -1) & 
            (t.Projects.ProjectId.Equals(projectId) | projectId == -1) & 
            (t.Subject.Contains(SearchText) | t.Description.Contains(SearchText) | SearchText == "" | SearchText == null) & 
            (t.Projects.Active == true) & 
            (t.Catagories.Active == true || t.Catagories==null) & 
            (t.LoggedBy.UserProfile.Companies.CompanyId == CompanyId) & 
            (assignedToGuid == rnd | t.AssignedTo.UserId.Equals(assignedToGuid))).OrderBy(SortField + " " + SortOrder); 

Quand il exécute génère cette requête SQL

exec sp_executesql N'SELECT 
[Project1].[C1] AS [C1], 
[Project1].[TaskId] AS [TaskId], 
[Project1].[Subject] AS [Subject], 
[Project1].[Description] AS [Description], 
[Project1].[EstimateDays] AS [EstimateDays], 
[Project1].[EstimateHours] AS [EstimateHours], 
[Project1].[DateLogged] AS [DateLogged], 
[Project1].[DateModified] AS [DateModified], 
[Project1].[AssignedTo] AS [AssignedTo], 
[Project1].[C2] AS [C2], 
[Project1].[CatagoryId] AS [CatagoryId], 
[Project1].[CatagoryName] AS [CatagoryName], 
[Project1].[CreatedOn] AS [CreatedOn], 
[Project1].[Active] AS [Active], 
[Project1].[CreatedBy] AS [CreatedBy], 
[Project1].[C3] AS [C3], 
[Project1].[ProjectId] AS [ProjectId], 
[Project1].[ProjectName] AS [ProjectName], 
[Project1].[CreatedOn1] AS [CreatedOn1], 
[Project1].[Active1] AS [Active1], 
[Project1].[CreatedBy1] AS [CreatedBy1], 
[Project1].[TaskStatusId] AS [TaskStatusId], 
[Project1].[StatusName] AS [StatusName], 
[Project1].[C4] AS [C4], 
[Project1].[ApplicationId] AS [ApplicationId], 
[Project1].[UserId] AS [UserId], 
[Project1].[UserName] AS [UserName], 
[Project1].[LoweredUserName] AS [LoweredUserName], 
[Project1].[MobileAlias] AS [MobileAlias], 
[Project1].[IsAnonymous] AS [IsAnonymous], 
[Project1].[LastActivityDate] AS [LastActivityDate], 
[Project1].[UserId1] AS [UserId1], 
[Project1].[UserId2] AS [UserId2] 
FROM (SELECT 
    [Filter1].[TaskId] AS [TaskId], 
    [Filter1].[Subject] AS [Subject], 
    [Filter1].[Description] AS [Description], 
    [Filter1].[AssignedTo] AS [AssignedTo], 
    [Filter1].[EstimateDays] AS [EstimateDays], 
    [Filter1].[EstimateHours] AS [EstimateHours], 
    [Filter1].[DateLogged] AS [DateLogged], 
    [Filter1].[DateModified] AS [DateModified], 
    [Filter1].[CatagoryId1] AS [CatagoryId], 
    [Filter1].[CatagoryName] AS [CatagoryName], 
    [Filter1].[CreatedBy1] AS [CreatedBy], 
    [Filter1].[CreatedOn1] AS [CreatedOn], 
    [Filter1].[Active1] AS [Active], 
    [Filter1].[ProjectId1] AS [ProjectId], 
    [Filter1].[ProjectName1] AS [ProjectName], 
    [Filter1].[CreatedOn2] AS [CreatedOn1], 
    [Filter1].[Active2] AS [Active1], 
    [Filter1].[CreatedBy2] AS [CreatedBy1], 
    [Filter1].[TaskStatusId1] AS [TaskStatusId], 
    [Filter1].[StatusName] AS [StatusName], 
    [Filter1].[ApplicationId1] AS [ApplicationId], 
    [Filter1].[UserId1] AS [UserId], 
    [Filter1].[UserName1] AS [UserName], 
    [Filter1].[LoweredUserName1] AS [LoweredUserName], 
    [Filter1].[MobileAlias1] AS [MobileAlias], 
    [Filter1].[IsAnonymous1] AS [IsAnonymous], 
    [Filter1].[LastActivityDate1] AS [LastActivityDate], 
    [Filter1].[UserId2] AS [UserId1], 
    [Join12].[UserId3] AS [UserId2], 
    1 AS [C1], 
    1 AS [C2], 
    1 AS [C3], 
    1 AS [C4] 
    FROM (SELECT [Extent1].[TaskId] AS [TaskId], [Extent1].[Subject] AS [Subject], [Extent1].[Description] AS [Description], [Extent1].[ProjectId] AS [ProjectId2], [Extent1].[TaskStatusId] AS [TaskStatusId2], [Extent1].[LoggedBy] AS [LoggedBy], [Extent1].[AssignedTo] AS [AssignedTo], [Extent1].[EstimateDays] AS [EstimateDays], [Extent1].[EstimateHours] AS [EstimateHours], [Extent1].[DateLogged] AS [DateLogged], [Extent1].[DateModified] AS [DateModified], [Extent1].[CatagoryId] AS [CatagoryId2], [Extent2].[ProjectId] AS [ProjectId3], [Extent2].[ProjectName] AS [ProjectName2], [Extent2].[CreatedOn] AS [CreatedOn3], [Extent2].[CreatedBy] AS [CreatedBy3], [Extent2].[Active] AS [Active3], [Extent3].[CatagoryId] AS [CatagoryId1], [Extent3].[CatagoryName] AS [CatagoryName], [Extent3].[CreatedBy] AS [CreatedBy1], [Extent3].[CreatedOn] AS [CreatedOn1], [Extent3].[Active] AS [Active1], [Join3].[ApplicationId2], [Join3].[UserId4], [Join3].[UserName2], [Join3].[LoweredUserName2], [Join3].[MobileAlias2], [Join3].[IsAnonymous2], [Join3].[LastActivityDate2], [Join3].[UserId5], [Join3].[CompanyId1], [Join3].[Forename1], [Join3].[Surname1], [Join3].[Active4], [Extent6].[UserId] AS [UserId6], [Extent6].[CompanyId] AS [CompanyId2], [Extent6].[Forename] AS [Forename2], [Extent6].[Surname] AS [Surname2], [Extent6].[Active] AS [Active5], [Extent7].[ProjectId] AS [ProjectId1], [Extent7].[ProjectName] AS [ProjectName1], [Extent7].[CreatedOn] AS [CreatedOn2], [Extent7].[CreatedBy] AS [CreatedBy4], [Extent7].[Active] AS [Active2], [Extent8].[ProjectId] AS [ProjectId4], [Extent8].[ProjectName] AS [ProjectName3], [Extent8].[CreatedOn] AS [CreatedOn4], [Extent8].[CreatedBy] AS [CreatedBy2], [Extent8].[Active] AS [Active6], [Extent9].[TaskStatusId] AS [TaskStatusId1], [Extent9].[StatusName] AS [StatusName], [Extent10].[ApplicationId] AS [ApplicationId1], [Extent10].[UserId] AS [UserId1], [Extent10].[UserName] AS [UserName1], [Extent10].[LoweredUserName] AS [LoweredUserName1], [Extent10].[MobileAlias] AS [MobileAlias1], [Extent10].[IsAnonymous] AS [IsAnonymous1], [Extent10].[LastActivityDate] AS [LastActivityDate1], [Join10].[ApplicationId3], [Join10].[UserId7], [Join10].[UserName3], [Join10].[LoweredUserName3], [Join10].[MobileAlias3], [Join10].[IsAnonymous3], [Join10].[LastActivityDate3], [Join10].[ApplicationId4], [Join10].[UserId2], [Join10].[Password], [Join10].[PasswordFormat], [Join10].[PasswordSalt], [Join10].[MobilePIN], [Join10].[Email], [Join10].[LoweredEmail], [Join10].[PasswordQuestion], [Join10].[PasswordAnswer], [Join10].[IsApproved], [Join10].[IsLockedOut], [Join10].[CreateDate], [Join10].[LastLoginDate], [Join10].[LastPasswordChangedDate], [Join10].[LastLockoutDate], [Join10].[FailedPasswordAttemptCount], [Join10].[FailedPasswordAttemptWindowStart], [Join10].[FailedPasswordAnswerAttemptCount], [Join10].[FailedPasswordAnswerAttemptWindowStart], [Join10].[Comment] 
     FROM   [dbo].[Tasks] AS [Extent1] 
     INNER JOIN [dbo].[Projects] AS [Extent2] ON [Extent1].[ProjectId] = [Extent2].[ProjectId] 
     LEFT OUTER JOIN [dbo].[Catagories] AS [Extent3] ON [Extent1].[CatagoryId] = [Extent3].[CatagoryId] 
     LEFT OUTER JOIN (SELECT [Extent4].[ApplicationId] AS [ApplicationId2], [Extent4].[UserId] AS [UserId4], [Extent4].[UserName] AS [UserName2], [Extent4].[LoweredUserName] AS [LoweredUserName2], [Extent4].[MobileAlias] AS [MobileAlias2], [Extent4].[IsAnonymous] AS [IsAnonymous2], [Extent4].[LastActivityDate] AS [LastActivityDate2], [Extent5].[UserId] AS [UserId5], [Extent5].[CompanyId] AS [CompanyId1], [Extent5].[Forename] AS [Forename1], [Extent5].[Surname] AS [Surname1], [Extent5].[Active] AS [Active4] 
      FROM [dbo].[aspnet_Users] AS [Extent4] 
      LEFT OUTER JOIN [dbo].[UserProfile] AS [Extent5] ON [Extent4].[UserId] = [Extent5].[UserId]) AS [Join3] ON [Extent1].[AssignedTo] = [Join3].[UserId4] 
     INNER JOIN [dbo].[UserProfile] AS [Extent6] ON [Join3].[UserId5] = [Extent6].[UserId] 
     LEFT OUTER JOIN [dbo].[Projects] AS [Extent7] ON [Extent1].[ProjectId] = [Extent7].[ProjectId] 
     LEFT OUTER JOIN [dbo].[Projects] AS [Extent8] ON [Extent1].[ProjectId] = [Extent8].[ProjectId] 
     LEFT OUTER JOIN [dbo].[TaskStatuses] AS [Extent9] ON [Extent1].[TaskStatusId] = [Extent9].[TaskStatusId] 
     LEFT OUTER JOIN [dbo].[aspnet_Users] AS [Extent10] ON [Extent1].[LoggedBy] = [Extent10].[UserId] 
     LEFT OUTER JOIN (SELECT [Extent11].[ApplicationId] AS [ApplicationId3], [Extent11].[UserId] AS [UserId7], [Extent11].[UserName] AS [UserName3], [Extent11].[LoweredUserName] AS [LoweredUserName3], [Extent11].[MobileAlias] AS [MobileAlias3], [Extent11].[IsAnonymous] AS [IsAnonymous3], [Extent11].[LastActivityDate] AS [LastActivityDate3], [Extent12].[ApplicationId] AS [ApplicationId4], [Extent12].[UserId] AS [UserId2], [Extent12].[Password] AS [Password], [Extent12].[PasswordFormat] AS [PasswordFormat], [Extent12].[PasswordSalt] AS [PasswordSalt], [Extent12].[MobilePIN] AS [MobilePIN], [Extent12].[Email] AS [Email], [Extent12].[LoweredEmail] AS [LoweredEmail], [Extent12].[PasswordQuestion] AS [PasswordQuestion], [Extent12].[PasswordAnswer] AS [PasswordAnswer], [Extent12].[IsApproved] AS [IsApproved], [Extent12].[IsLockedOut] AS [IsLockedOut], [Extent12].[CreateDate] AS [CreateDate], [Extent12].[LastLoginDate] AS [LastLoginDate], [Extent12].[LastPasswordChangedDate] AS [LastPasswordChangedDate], [Extent12].[LastLockoutDate] AS [LastLockoutDate], [Extent12].[FailedPasswordAttemptCount] AS [FailedPasswordAttemptCount], [Extent12].[FailedPasswordAttemptWindowStart] AS [FailedPasswordAttemptWindowStart], [Extent12].[FailedPasswordAnswerAttemptCount] AS [FailedPasswordAnswerAttemptCount], [Extent12].[FailedPasswordAnswerAttemptWindowStart] AS [FailedPasswordAnswerAttemptWindowStart], [Extent12].[Comment] AS [Comment] 
      FROM [dbo].[aspnet_Users] AS [Extent11] 
      LEFT OUTER JOIN [dbo].[aspnet_Membership] AS [Extent12] ON [Extent11].[UserId] = [Extent12].[UserId]) AS [Join10] ON [Extent1].[LoggedBy] = [Join10].[UserId7] 
     WHERE (1 = [Extent2].[Active]) AND ((1 = [Extent3].[Active]) OR ([Extent3].[CatagoryId] IS NULL))) AS [Filter1] 
    LEFT OUTER JOIN (SELECT [Extent13].[ApplicationId] AS [ApplicationId], [Extent13].[UserId] AS [UserId8], [Extent13].[UserName] AS [UserName], [Extent13].[LoweredUserName] AS [LoweredUserName], [Extent13].[MobileAlias] AS [MobileAlias], [Extent13].[IsAnonymous] AS [IsAnonymous], [Extent13].[LastActivityDate] AS [LastActivityDate], [Extent14].[UserId] AS [UserId3], [Extent14].[CompanyId] AS [CompanyId], [Extent14].[Forename] AS [Forename], [Extent14].[Surname] AS [Surname], [Extent14].[Active] AS [Active] 
     FROM [dbo].[aspnet_Users] AS [Extent13] 
     LEFT OUTER JOIN [dbo].[UserProfile] AS [Extent14] ON [Extent13].[UserId] = [Extent14].[UserId]) AS [Join12] ON [Filter1].[LoggedBy] = [Join12].[UserId8] 
    WHERE (([Filter1].[TaskStatusId2] = @p__linq__49) OR (-1 = @p__linq__50)) AND (([Filter1].[ProjectId2] = @p__linq__51) OR (-1 = @p__linq__52)) AND (((CAST(CHARINDEX(@p__linq__53, [Filter1].[Subject]) AS int)) > 0) OR ((CAST(CHARINDEX(@p__linq__54, [Filter1].[Description]) AS int)) > 0) OR (N'''' = @p__linq__55) OR (@p__linq__56 IS NULL)) AND ([Filter1].[CompanyId2] = @p__linq__57) AND ((@p__linq__58 = @p__linq__59) OR ([Filter1].[LoggedBy] = @p__linq__60)) 
) AS [Project1] 
ORDER BY [Project1].[TaskId] ASC',N'@p__linq__49 int,@p__linq__50 int,@p__linq__51 int,@p__linq__52 int,@p__linq__53 nvarchar(4000),@p__linq__54 nvarchar(4000),@p__linq__55 nvarchar(4000),@p__linq__56 nvarchar(4000),@p__linq__57 int,@p__linq__58 uniqueidentifier,@p__linq__59 uniqueidentifier,@p__linq__60 uniqueidentifier',@p__linq__49=1,@p__linq__50=1,@p__linq__51=2,@p__linq__52=2,@p__linq__53=NULL,@p__linq__54=NULL,@p__linq__55=NULL,@p__linq__56=NULL,@p__linq__57=1,@p__linq__58='00000000-0000-0000-0000-000000000000',@p__linq__59='00000000-0000-0000-0000-000000000000',@p__linq__60='00000000-0000-0000-0000-000000000000' 

Je suis sûr qu'il doit être un moyen de faire en sorte que Linq génère un SQL plus convivial. Si j'ai écrit cette même requête, cela pourrait être fait dans environ 5 jointures et pas de sélections internes, est-il possible de faire en sorte que Linq mette tout cela en ordre?

Merci

Gavin

Répondre

1

Le grand LINQ requête EF crée est juste une lacune de la première version de l'Entity Framework. Cependant, votre requête contient l'expression .OrderBy (SortField + "" + SortOrder), je crois que la manière préférée d'écrire ceci serait .OrderBy (SortField) .ThenBy (SortOrder). Aussi, y a-t-il une raison que vous utilisez | au lieu de || et & au lieu de & & dans certains endroits?

IQueryable<Tasks> tl = db.Tasks 
           .Include("Catagories") 
           .Include("Projects") 
           .Include("TaskStatuses") 
           .Include("AssignedTo") 
           .Where 
            (t => (t.TaskStatuses.TaskStatusId.Equals(currentStatus) | currentStatus == -1) & 
            (t.Projects.ProjectId.Equals(projectId) | projectId == -1) & 
            (t.Subject.Contains(SearchText) | t.Description.Contains(SearchText) | SearchText == "" | SearchText == null) & 
            (t.Projects.Active == true) & 
            (t.Catagories.Active == true || t.Catagories==null) & 
            (t.LoggedBy.UserProfile.Companies.CompanyId == CompanyId) & 
            (assignedToGuid == rnd | t.AssignedTo.UserId.Equals(assignedToGuid))).OrderBy(SortField + " " + SortOrder); 
+0

Six versions dans ce qui est sûr de dire que ce n'était pas seulement un défaut de la première version. – Casey

Questions connexes