1

我想知道是否有更好的方法来构造我的 linq 查询(我正在使用 EF CodeFirst)来访问我的表。现在,它产生以下查询:

exec sp_executesql N'SELECT 
[Project4].[Id] AS [Id], 
[Project4].[First] AS [First], 
[Project4].[Last] AS [Last], 
[Project4].[Email] AS [Email]
FROM ( SELECT 
    [Project3].[Id] AS [Id], 
    [Project3].[First] AS [First], 
    [Project3].[Last] AS [Last], 
    [Project3].[Email] AS [Email],
    CASE WHEN ([Extent5].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
    FROM   (SELECT 
        [Project2].[Id] AS [Id], 
        [Project2].[First] AS [First], 
        [Project2].[Last] AS [Last], 
        [Project2].[Email] AS [Email]
        (SELECT 
            SUM([Extent4].[Data]) AS [A1]
            FROM [dbo].[EventHistory] AS [Extent4]
            WHERE [Project2].[Id] = [Extent4].[UserId]) AS [C1]
        FROM ( SELECT 
            [Extent1].[Id] AS [Id], 
            [Extent1].[First] AS [First], 
            [Extent1].[Last] AS [Last], 
            [Extent1].[Email] AS [Email]
            (SELECT 
                SUM([Extent3].[Data]) AS [A1]
                FROM [dbo].[EventHistory] AS [Extent3]
                WHERE [Extent1].[Id] = [Extent3].[UserId]) AS [C1]
            FROM [dbo].[User] AS [Extent1]
            WHERE ( EXISTS (SELECT 
                1 AS [C1]
                FROM [dbo].[EventHistory] AS [Extent2]
                WHERE [Extent1].[Id] = [Extent2].[UserId]
            )) AND ([Extent1].[Id] = @p__linq__0)
        )  AS [Project2]
        WHERE [Project2].[C1] >= @p__linq__1 ) AS [Project3]
    LEFT OUTER JOIN [dbo].[EventHistory] AS [Extent5] ON [Project3].[Id] = [Extent5].  [UserId]
    WHERE [Project3].[C1] <= @p__linq__2
)  AS [Project4]
ORDER BY [Project4].[Id] ASC, [Project4].[C1] ASC',N'@p__linq__0 int,@p__linq__1 int,@p__linq__2 int',@p__linq__0=1717,@p__linq__1=300,@p__linq__2=400

...这对我来说似乎很可怕,为什么它会创建所有这些不同的子选择?- 对我来说,它真的应该产生类似的东西:

select u.id, first, last, email, e.*
from user u 
left join eventhistory e
    on e.userid = u.id
   and e.data <= @param1
   and e.data >= @param2
   and u.id = @id

我的代码看起来像这样:

IQueryable<User> query = from users in this.DataContext.Users.Include("EventHistoryList") 
                         where users.EventHistoryList.Any()
                         select users;

if (playerId.HasValue)
    query = query.Where(u => u.Id == playerId.Value);

if (dataLow.HasValue)
    query = query.Where(u => u.EventHistoryList.Sum(p => p.Data) >= dataLow.Value);

if (dataHigh.HasValue)
    query = query.Where(u => u.EventHistoryList.Sum(p => p.Data) <= dataHigh.Value);

query = query.OrderByDescending(orderBy).Skip(startEntity).Take(pageSize).ToList();

任何帮助,将不胜感激。谢谢!

4

1 回答 1

1

看起来其中一个子选择处理分页,而其他选择是必要的,因为您正在对具有 0..* 关系的表应用聚合函数。我确信可以使查询看起来更好,但我不认为它是不必要的低效。

您认为它应该生成的查询将从数据库中获取整个结果集,并且还需要一个子选择来应用聚合函数。从数据库中获取整个结果集并在之后进行分页是非常低效的。

于 2012-05-29T16:37:52.777 回答