Challenge: Getting Linq-to-Entities to generate decent SQL without unnecessary joins

后端 未结 3 1453
心在旅途
心在旅途 2021-02-10 13:09

I recently came across a question in the Entity Framework forum on msdn: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/bb72fae4-0709-48f2-8f85-31

3条回答
  •  青春惊慌失措
    2021-02-10 13:19

    If I was that worried about the crazy SQL, I just wouldn't do any of the grouping in the database. I would first query all of the data I needed by finishing it off with a ToList() while using the Include function to load all the data in a single select.

    Here's my final result:

    var list = from o in _entities.orderT.Include("personT")
               .Where(p => p.personT.person_id == person_id && 
                           p.personT.created >= fromTime && 
                           p.personT.created <= toTime).ToList()
               group o by new { o.name, o.personT.created.Year, o.personT.created.Month, o.personT.created.Day } into g
               orderby g.Key.name
               select new { g.Key, count = g.Sum(x => x.price) };
    

    This results in a much simpler select:

    SELECT 
    1 AS [C1], 
    [Extent1].[order_id] AS [order_id], 
    [Extent1].[name] AS [name], 
    [Extent1].[created] AS [created], 
    [Extent1].[price] AS [price], 
    [Extent4].[person_id] AS [person_id], 
    [Extent4].[first_name] AS [first_name], 
    [Extent4].[last_name] AS [last_name], 
    [Extent4].[created] AS [created1]
    FROM    [dbo].[orderT] AS [Extent1]
    LEFT OUTER JOIN [dbo].[personT] AS [Extent2] ON [Extent1].[person_id] = [Extent2].[person_id]
    INNER JOIN [dbo].[personT] AS [Extent3] ON [Extent1].[person_id] = [Extent3].[person_id]
    LEFT OUTER JOIN [dbo].[personT] AS [Extent4] ON [Extent1].[person_id] = [Extent4].[person_id]
    WHERE ([Extent1].[person_id] = @p__linq__1) AND ([Extent2].[created] >= @p__linq__2) AND ([Extent3].[created] <= @p__linq__3)
    

    Additionally, with the example data provided, SQL Profiler only notices a 3 ms increase in duration of the SQL call.

    Personally, I think that anyone that whines about not liking the output SQL of an ORM layer should go back to using Stored Procedures and Datasets. They simply aren't ready to evolve yet, and need to spend a few more years in the proverbial oven. :)

提交回复
热议问题