Optimize entity framework query

前端 未结 5 1425
星月不相逢
星月不相逢 2020-12-02 12:27

I\'m trying to make a stackoverflow clone in my own time to learn EF6 and MVC5, i\'m currently using OWin for authentication.

Everything works fine when i have like

5条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-02 13:00

    Most likely the problem you are experiencing is a Cartesian product.

    Based on just some sample data:

    var query = ctx.Questions // 50 
      .Include("Attachments") // 20                                
      .Include("Location") // 10
      .Include("CreatedBy") // 5
      .Include("Tags") // 5
      .Include("Upvotes") // 5
      .Include("Upvotes.CreatedBy") // 5
      .Include("Downvotes") // 5
      .Include("Downvotes.CreatedBy") // 5
    
      // Where Blah
      // Order By Blah
    

    This returns a number of rows upwards of

    50 x 20 x 10 x 5 x 5 x 5 x 5 x 5 x 5 = 156,250,000
    

    Seriously... that is an INSANE number of rows to return.

    You really have two options if you are having this issue:

    First: The easy way, rely on Entity-Framework to wire up models automagically as they enter the context. And afterwards, use the entities AsNoTracking() and dispose of the context.

    // Continuing with the query above:
    
    var questions = query.Select(q => q);
    var attachments = query.Select(q => q.Attachments);
    var locations = query.Select(q => q.Locations);
    

    This will make a request per table, but instead of 156 MILLION rows, you only download 110 rows. But the cool part is they are all wired up in EF Context Cache memory, so now the questions variable is completely populated.

    Second: Create a stored procedure that returns multiple tables and have EF materialize the classes.

提交回复
热议问题