2014-05-12 12 views
6

Non mi aspettavo una query generato come questo ...utilizzando. Include nel framework di entità creare query enorme?

lasciarsi andare indietro, se continuo a uno comprendono, la query guardare bene, si fa un semplice sinistra unirsi

Query:

using (var db = new Context()) 
{ 
    var data = db.MainTables.Include(x => x.LookupTables) 
          .Where(d => d.MainId == 10) 
          .FirstOrDefault(); 
} 

SQL generato:

Opened connection at 2014-05-12 17:37:10 -04:00 
SELECT 
    [Project1].[MainId] AS [MainId], 
    [Project1].[C1] AS [C1], 
    [Project1].[LookupId] AS [LookupId] 
    FROM (SELECT 
     [Limit1].[MainId] AS [MainId], 
     [Extent2].[LookupId] AS [LookupId], 
     CASE WHEN ([Extent2].[MainId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
     FROM (SELECT TOP (1) [Extent1].[MainId] AS [MainId] 
      FROM [dbo].[MainTable] AS [Extent1] 
      WHERE 10 = [Extent1].[MainId]) AS [Limit1] 
     LEFT OUTER JOIN [dbo].[MainTable_LookupTable] AS [Extent2] ON [Limit1].[MainId] = [Extent2].[MainId] 
    ) AS [Project1] 
    ORDER BY [Project1].[MainId] ASC, [Project1].[C1] ASC 
-- Executing at 2014-05-12 17:37:11 -04:00 
-- Completed in 11 ms with result: SqlDataReader 

Closed connection at 2014-05-12 17:37:11 -04:00 

se ho più di uno, la query impazzire come l'inferno con UNION ALL ...

è un comportamento previsto? se sì, è possibile mantenere il comportamento di una inclusione mentre ne usi più di una, una semplice unione sinistra per tutte loro?

Modello:

dbModel2

Query:

using (var db = new Context()) 
{ 
    var data = db.MainTables.Include(x => x.LookupTables) 
          .Include(x => x.MainTable_MoreData) 
          .Include(x => x.MaintTable_DataLookup) 
          .Include(x => x.MainTable_EvenMoreData) 
          .Where(d => d.MainId == 10) 
          .FirstOrDefault() 

} 

SQL generato:

Opened connection at 2014-05-12 18:00:56 -04:00 
SELECT 
    [UnionAll3].[C2] AS [C1], 
    [UnionAll3].[C3] AS [C2], 
    [UnionAll3].[C4] AS [C3], 
    [UnionAll3].[C5] AS [C4], 
    [UnionAll3].[C6] AS [C5], 
    [UnionAll3].[C7] AS [C6], 
    [UnionAll3].[C8] AS [C7], 
    [UnionAll3].[C9] AS [C8], 
    [UnionAll3].[C10] AS [C9], 
    [UnionAll3].[C11] AS [C10], 
    [UnionAll3].[C12] AS [C11], 
    [UnionAll3].[C13] AS [C12], 
    [UnionAll3].[C1] AS [C13], 
    [UnionAll3].[C14] AS [C14], 
    [UnionAll3].[C15] AS [C15], 
    [UnionAll3].[C16] AS [C16], 
    [UnionAll3].[C17] AS [C17], 
    [UnionAll3].[C18] AS [C18], 
    [UnionAll3].[C19] AS [C19], 
    [UnionAll3].[C20] AS [C20], 
    [UnionAll3].[C21] AS [C21], 
    [UnionAll3].[C22] AS [C22], 
    [UnionAll3].[C23] AS [C23], 
    [UnionAll3].[C24] AS [C24], 
    [UnionAll3].[C25] AS [C25], 
    [UnionAll3].[C26] AS [C26], 
    [UnionAll3].[C27] AS [C27], 
    [UnionAll3].[C28] AS [C28], 
    [UnionAll3].[C29] AS [C29], 
    [UnionAll3].[C30] AS [C30], 
    [UnionAll3].[C31] AS [C31], 
    [UnionAll3].[C32] AS [C32], 
    [UnionAll3].[C33] AS [C33], 
    [UnionAll3].[C34] AS [C34], 
    [UnionAll3].[C35] AS [C35], 
    [UnionAll3].[C36] AS [C36], 
    [UnionAll3].[C37] AS [C37], 
    [UnionAll3].[C38] AS [C38], 
    [UnionAll3].[C39] AS [C39], 
    [UnionAll3].[C40] AS [C40], 
    [UnionAll3].[C41] AS [C41], 
    [UnionAll3].[C42] AS [C42], 
    [UnionAll3].[C43] AS [C43], 
    [UnionAll3].[C44] AS [C44], 
    [UnionAll3].[C45] AS [C45], 
    [UnionAll3].[C46] AS [C46], 
    [UnionAll3].[C47] AS [C47], 
    [UnionAll3].[C48] AS [C48], 
    [UnionAll3].[C49] AS [C49], 
    [UnionAll3].[C50] AS [C50], 
    [UnionAll3].[C51] AS [C51] 
    FROM (SELECT 
     [UnionAll2].[C1] AS [C1], 
     [UnionAll2].[C2] AS [C2], 
     [UnionAll2].[C3] AS [C3], 
     [UnionAll2].[C4] AS [C4], 
     [UnionAll2].[C5] AS [C5], 
     [UnionAll2].[C6] AS [C6], 
     [UnionAll2].[C7] AS [C7], 
     [UnionAll2].[C8] AS [C8], 
     [UnionAll2].[C9] AS [C9], 
     [UnionAll2].[C10] AS [C10], 
     [UnionAll2].[C11] AS [C11], 
     [UnionAll2].[C12] AS [C12], 
     [UnionAll2].[C13] AS [C13], 
     [UnionAll2].[C14] AS [C14], 
     [UnionAll2].[C15] AS [C15], 
     [UnionAll2].[C16] AS [C16], 
     [UnionAll2].[C17] AS [C17], 
     [UnionAll2].[C18] AS [C18], 
     [UnionAll2].[C19] AS [C19], 
     [UnionAll2].[C20] AS [C20], 
     [UnionAll2].[C21] AS [C21], 
     [UnionAll2].[C22] AS [C22], 
     [UnionAll2].[C23] AS [C23], 
     [UnionAll2].[C24] AS [C24], 
     [UnionAll2].[C25] AS [C25], 
     [UnionAll2].[C26] AS [C26], 
     [UnionAll2].[C27] AS [C27], 
     [UnionAll2].[C28] AS [C28], 
     [UnionAll2].[C29] AS [C29], 
     [UnionAll2].[C30] AS [C30], 
     [UnionAll2].[C31] AS [C31], 
     [UnionAll2].[C32] AS [C32], 
     [UnionAll2].[C33] AS [C33], 
     [UnionAll2].[C34] AS [C34], 
     [UnionAll2].[C35] AS [C35], 
     [UnionAll2].[C36] AS [C36], 
     [UnionAll2].[C37] AS [C37], 
     [UnionAll2].[C38] AS [C38], 
     [UnionAll2].[C39] AS [C39], 
     [UnionAll2].[C40] AS [C40], 
     [UnionAll2].[C41] AS [C41], 
     [UnionAll2].[C42] AS [C42], 
     [UnionAll2].[C43] AS [C43], 
     [UnionAll2].[C44] AS [C44], 
     [UnionAll2].[C45] AS [C45], 
     [UnionAll2].[C46] AS [C46], 
     [UnionAll2].[C47] AS [C47], 
     [UnionAll2].[C48] AS [C48], 
     [UnionAll2].[C49] AS [C49], 
     [UnionAll2].[C50] AS [C50], 
     [UnionAll2].[C51] AS [C51] 
     FROM (SELECT 
      [UnionAll1].[C1] AS [C1], 
      [UnionAll1].[MainId] AS [C2], 
      [UnionAll1].[MainId1] AS [C3], 
      [UnionAll1].[Field1] AS [C4], 
      [UnionAll1].[Field11] AS [C5], 
      [UnionAll1].[Field12] AS [C6], 
      [UnionAll1].[Field13] AS [C7], 
      [UnionAll1].[Field14] AS [C8], 
      [UnionAll1].[Field15] AS [C9], 
      [UnionAll1].[Field16] AS [C10], 
      [UnionAll1].[Field17] AS [C11], 
      [UnionAll1].[Field18] AS [C12], 
      [UnionAll1].[Field19] AS [C13], 
      [UnionAll1].[LookupId] AS [C14], 
      [UnionAll1].[Field161] AS [C15], 
      [UnionAll1].[Field151] AS [C16], 
      [UnionAll1].[Field141] AS [C17], 
      [UnionAll1].[Field131] AS [C18], 
      [UnionAll1].[Field121] AS [C19], 
      [UnionAll1].[Field111] AS [C20], 
      [UnionAll1].[Field110] AS [C21], 
      [UnionAll1].[C2] AS [C22], 
      [UnionAll1].[C3] AS [C23], 
      [UnionAll1].[C4] AS [C24], 
      [UnionAll1].[C5] AS [C25], 
      [UnionAll1].[C6] AS [C26], 
      [UnionAll1].[C7] AS [C27], 
      [UnionAll1].[C8] AS [C28], 
      [UnionAll1].[C9] AS [C29], 
      [UnionAll1].[C10] AS [C30], 
      [UnionAll1].[C11] AS [C31], 
      [UnionAll1].[C12] AS [C32], 
      [UnionAll1].[C13] AS [C33], 
      [UnionAll1].[C14] AS [C34], 
      [UnionAll1].[C15] AS [C35], 
      [UnionAll1].[C16] AS [C36], 
      [UnionAll1].[C17] AS [C37], 
      [UnionAll1].[C18] AS [C38], 
      [UnionAll1].[C19] AS [C39], 
      [UnionAll1].[C20] AS [C40], 
      [UnionAll1].[C21] AS [C41], 
      [UnionAll1].[C22] AS [C42], 
      [UnionAll1].[C23] AS [C43], 
      [UnionAll1].[C24] AS [C44], 
      [UnionAll1].[C25] AS [C45], 
      [UnionAll1].[C26] AS [C46], 
      [UnionAll1].[C27] AS [C47], 
      [UnionAll1].[C28] AS [C48], 
      [UnionAll1].[C29] AS [C49], 
      [UnionAll1].[C30] AS [C50], 
      [UnionAll1].[C31] AS [C51] 
      FROM (SELECT 
       CASE WHEN ([Join1].[MainId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1], 
       [Limit1].[MainId] AS [MainId], 
       [Limit1].[MainId] AS [MainId1], 
       [Limit1].[Field1] AS [Field1], 
       [Limit1].[Field11] AS [Field11], 
       [Limit1].[Field12] AS [Field12], 
       [Limit1].[Field13] AS [Field13], 
       [Limit1].[Field14] AS [Field14], 
       [Limit1].[Field15] AS [Field15], 
       [Limit1].[Field16] AS [Field16], 
       [Limit1].[Field17] AS [Field17], 
       [Limit1].[Field18] AS [Field18], 
       [Limit1].[Field19] AS [Field19], 
       [Join1].[LookupId1] AS [LookupId], 
       [Join1].[Field16] AS [Field161], 
       [Join1].[Field15] AS [Field151], 
       [Join1].[Field14] AS [Field141], 
       [Join1].[Field13] AS [Field131], 
       [Join1].[Field12] AS [Field121], 
       [Join1].[Field11] AS [Field111], 
       [Join1].[Field1] AS [Field110], 
       CAST(NULL AS int) AS [C2], 
       CAST(NULL AS int) AS [C3], 
       CAST(NULL AS varchar(1)) AS [C4], 
       CAST(NULL AS varchar(1)) AS [C5], 
       CAST(NULL AS varchar(1)) AS [C6], 
       CAST(NULL AS varchar(1)) AS [C7], 
       CAST(NULL AS varchar(1)) AS [C8], 
       CAST(NULL AS varchar(1)) AS [C9], 
       CAST(NULL AS varchar(1)) AS [C10], 
       CAST(NULL AS int) AS [C11], 
       CAST(NULL AS varchar(1)) AS [C12], 
       CAST(NULL AS varchar(1)) AS [C13], 
       CAST(NULL AS varchar(1)) AS [C14], 
       CAST(NULL AS varchar(1)) AS [C15], 
       CAST(NULL AS varchar(1)) AS [C16], 
       CAST(NULL AS varchar(1)) AS [C17], 
       CAST(NULL AS varchar(1)) AS [C18], 
       CAST(NULL AS int) AS [C19], 
       CAST(NULL AS int) AS [C20], 
       CAST(NULL AS int) AS [C21], 
       CAST(NULL AS varchar(1)) AS [C22], 
       CAST(NULL AS varchar(1)) AS [C23], 
       CAST(NULL AS varchar(1)) AS [C24], 
       CAST(NULL AS varchar(1)) AS [C25], 
       CAST(NULL AS varchar(1)) AS [C26], 
       CAST(NULL AS varchar(1)) AS [C27], 
       CAST(NULL AS varchar(1)) AS [C28], 
       CAST(NULL AS varchar(1)) AS [C29], 
       CAST(NULL AS varchar(1)) AS [C30], 
       CAST(NULL AS int) AS [C31] 
       FROM (SELECT TOP (1) [Extent1].[MainId] AS [MainId], [Extent1].[Field1] AS [Field1], [Extent1].[Field11] AS [Field11], [Extent1].[Field12] AS [Field12], [Extent1].[Field13] AS [Field13], [Extent1].[Field14] AS [Field14], [Extent1].[Field15] AS [Field15], [Extent1].[Field16] AS [Field16], [Extent1].[Field17] AS [Field17], [Extent1].[Field18] AS [Field18], [Extent1].[Field19] AS [Field19] 
        FROM [dbo].[MainTable] AS [Extent1] 
        WHERE 10 = [Extent1].[MainId]) AS [Limit1] 
       LEFT OUTER JOIN (SELECT [Extent2].[MainId] AS [MainId], [Extent3].[LookupId] AS [LookupId1], [Extent3].[Field16] AS [Field16], [Extent3].[Field15] AS [Field15], [Extent3].[Field14] AS [Field14], [Extent3].[Field13] AS [Field13], [Extent3].[Field12] AS [Field12], [Extent3].[Field11] AS [Field11], [Extent3].[Field1] AS [Field1] 
        FROM [dbo].[MainTable_LookupTable] AS [Extent2] 
        INNER JOIN [dbo].[LookupTable] AS [Extent3] ON [Extent3].[LookupId] = [Extent2].[LookupId]) AS [Join1] ON [Limit1].[MainId] = [Join1].[MainId] 
      UNION ALL 
       SELECT 
       2 AS [C1], 
       [Limit2].[MainId] AS [MainId], 
       [Limit2].[MainId] AS [MainId1], 
       [Limit2].[Field1] AS [Field1], 
       [Limit2].[Field11] AS [Field11], 
       [Limit2].[Field12] AS [Field12], 
       [Limit2].[Field13] AS [Field13], 
       [Limit2].[Field14] AS [Field14], 
       [Limit2].[Field15] AS [Field15], 
       [Limit2].[Field16] AS [Field16], 
       [Limit2].[Field17] AS [Field17], 
       [Limit2].[Field18] AS [Field18], 
       [Limit2].[Field19] AS [Field19], 
       CAST(NULL AS int) AS [C2], 
       CAST(NULL AS varchar(1)) AS [C3], 
       CAST(NULL AS varchar(1)) AS [C4], 
       CAST(NULL AS varchar(1)) AS [C5], 
       CAST(NULL AS varchar(1)) AS [C6], 
       CAST(NULL AS varchar(1)) AS [C7], 
       CAST(NULL AS varchar(1)) AS [C8], 
       CAST(NULL AS varchar(1)) AS [C9], 
       [Extent5].[DataId] AS [DataId], 
       [Extent5].[MainId] AS [MainId2], 
       [Extent5].[SomeData] AS [SomeData], 
       [Extent5].[Field1] AS [Field110], 
       [Extent5].[Field11] AS [Field111], 
       [Extent5].[Field12] AS [Field121], 
       [Extent5].[Field13] AS [Field131], 
       [Extent5].[Field14] AS [Field141], 
       [Extent5].[Field15] AS [Field151], 
       CAST(NULL AS int) AS [C10], 
       CAST(NULL AS varchar(1)) AS [C11], 
       CAST(NULL AS varchar(1)) AS [C12], 
       CAST(NULL AS varchar(1)) AS [C13], 
       CAST(NULL AS varchar(1)) AS [C14], 
       CAST(NULL AS varchar(1)) AS [C15], 
       CAST(NULL AS varchar(1)) AS [C16], 
       CAST(NULL AS varchar(1)) AS [C17], 
       CAST(NULL AS int) AS [C18], 
       CAST(NULL AS int) AS [C19], 
       CAST(NULL AS int) AS [C20], 
       CAST(NULL AS varchar(1)) AS [C21], 
       CAST(NULL AS varchar(1)) AS [C22], 
       CAST(NULL AS varchar(1)) AS [C23], 
       CAST(NULL AS varchar(1)) AS [C24], 
       CAST(NULL AS varchar(1)) AS [C25], 
       CAST(NULL AS varchar(1)) AS [C26], 
       CAST(NULL AS varchar(1)) AS [C27], 
       CAST(NULL AS varchar(1)) AS [C28], 
       CAST(NULL AS varchar(1)) AS [C29], 
       CAST(NULL AS int) AS [C30] 
       FROM (SELECT TOP (1) [Extent4].[MainId] AS [MainId], [Extent4].[Field1] AS [Field1], [Extent4].[Field11] AS [Field11], [Extent4].[Field12] AS [Field12], [Extent4].[Field13] AS [Field13], [Extent4].[Field14] AS [Field14], [Extent4].[Field15] AS [Field15], [Extent4].[Field16] AS [Field16], [Extent4].[Field17] AS [Field17], [Extent4].[Field18] AS [Field18], [Extent4].[Field19] AS [Field19] 
        FROM [dbo].[MainTable] AS [Extent4] 
        WHERE 10 = [Extent4].[MainId]) AS [Limit2] 
       INNER JOIN [dbo].[MainTable_MoreData] AS [Extent5] ON [Limit2].[MainId] = [Extent5].[MainId]) AS [UnionAll1] 
     UNION ALL 
      SELECT 
      3 AS [C1], 
      [Limit3].[MainId] AS [MainId], 
      [Limit3].[MainId] AS [MainId1], 
      [Limit3].[Field1] AS [Field1], 
      [Limit3].[Field11] AS [Field11], 
      [Limit3].[Field12] AS [Field12], 
      [Limit3].[Field13] AS [Field13], 
      [Limit3].[Field14] AS [Field14], 
      [Limit3].[Field15] AS [Field15], 
      [Limit3].[Field16] AS [Field16], 
      [Limit3].[Field17] AS [Field17], 
      [Limit3].[Field18] AS [Field18], 
      [Limit3].[Field19] AS [Field19], 
      CAST(NULL AS int) AS [C2], 
      CAST(NULL AS varchar(1)) AS [C3], 
      CAST(NULL AS varchar(1)) AS [C4], 
      CAST(NULL AS varchar(1)) AS [C5], 
      CAST(NULL AS varchar(1)) AS [C6], 
      CAST(NULL AS varchar(1)) AS [C7], 
      CAST(NULL AS varchar(1)) AS [C8], 
      CAST(NULL AS varchar(1)) AS [C9], 
      CAST(NULL AS int) AS [C10], 
      CAST(NULL AS int) AS [C11], 
      CAST(NULL AS varchar(1)) AS [C12], 
      CAST(NULL AS varchar(1)) AS [C13], 
      CAST(NULL AS varchar(1)) AS [C14], 
      CAST(NULL AS varchar(1)) AS [C15], 
      CAST(NULL AS varchar(1)) AS [C16], 
      CAST(NULL AS varchar(1)) AS [C17], 
      CAST(NULL AS varchar(1)) AS [C18], 
      [Extent7].[MainId] AS [MainId2], 
      [Extent7].[Data] AS [Data], 
      [Extent7].[Field1] AS [Field110], 
      [Extent7].[Field11] AS [Field111], 
      [Extent7].[Field12] AS [Field121], 
      [Extent7].[Field14] AS [Field141], 
      [Extent7].[Field15] AS [Field151], 
      [Extent7].[Field13] AS [Field131], 
      [Extent7].[MainId] AS [MainId3], 
      CAST(NULL AS int) AS [C19], 
      CAST(NULL AS int) AS [C20], 
      CAST(NULL AS varchar(1)) AS [C21], 
      CAST(NULL AS varchar(1)) AS [C22], 
      CAST(NULL AS varchar(1)) AS [C23], 
      CAST(NULL AS varchar(1)) AS [C24], 
      CAST(NULL AS varchar(1)) AS [C25], 
      CAST(NULL AS varchar(1)) AS [C26], 
      CAST(NULL AS varchar(1)) AS [C27], 
      CAST(NULL AS varchar(1)) AS [C28], 
      CAST(NULL AS varchar(1)) AS [C29], 
      CAST(NULL AS int) AS [C30] 
      FROM (SELECT TOP (1) [Extent6].[MainId] AS [MainId], [Extent6].[Field1] AS [Field1], [Extent6].[Field11] AS [Field11], [Extent6].[Field12] AS [Field12], [Extent6].[Field13] AS [Field13], [Extent6].[Field14] AS [Field14], [Extent6].[Field15] AS [Field15], [Extent6].[Field16] AS [Field16], [Extent6].[Field17] AS [Field17], [Extent6].[Field18] AS [Field18], [Extent6].[Field19] AS [Field19] 
       FROM [dbo].[MainTable] AS [Extent6] 
       WHERE 10 = [Extent6].[MainId]) AS [Limit3] 
      INNER JOIN [dbo].[MaintTable_DataLookup] AS [Extent7] ON [Limit3].[MainId] = [Extent7].[MainId]) AS [UnionAll2] 
    UNION ALL 
     SELECT 
     4 AS [C1], 
     [Limit4].[MainId] AS [MainId], 
     [Limit4].[MainId] AS [MainId1], 
     [Limit4].[Field1] AS [Field1], 
     [Limit4].[Field11] AS [Field11], 
     [Limit4].[Field12] AS [Field12], 
     [Limit4].[Field13] AS [Field13], 
     [Limit4].[Field14] AS [Field14], 
     [Limit4].[Field15] AS [Field15], 
     [Limit4].[Field16] AS [Field16], 
     [Limit4].[Field17] AS [Field17], 
     [Limit4].[Field18] AS [Field18], 
     [Limit4].[Field19] AS [Field19], 
     CAST(NULL AS int) AS [C2], 
     CAST(NULL AS varchar(1)) AS [C3], 
     CAST(NULL AS varchar(1)) AS [C4], 
     CAST(NULL AS varchar(1)) AS [C5], 
     CAST(NULL AS varchar(1)) AS [C6], 
     CAST(NULL AS varchar(1)) AS [C7], 
     CAST(NULL AS varchar(1)) AS [C8], 
     CAST(NULL AS varchar(1)) AS [C9], 
     CAST(NULL AS int) AS [C10], 
     CAST(NULL AS int) AS [C11], 
     CAST(NULL AS varchar(1)) AS [C12], 
     CAST(NULL AS varchar(1)) AS [C13], 
     CAST(NULL AS varchar(1)) AS [C14], 
     CAST(NULL AS varchar(1)) AS [C15], 
     CAST(NULL AS varchar(1)) AS [C16], 
     CAST(NULL AS varchar(1)) AS [C17], 
     CAST(NULL AS varchar(1)) AS [C18], 
     CAST(NULL AS int) AS [C19], 
     CAST(NULL AS varchar(1)) AS [C20], 
     CAST(NULL AS varchar(1)) AS [C21], 
     CAST(NULL AS varchar(1)) AS [C22], 
     CAST(NULL AS varchar(1)) AS [C23], 
     CAST(NULL AS varchar(1)) AS [C24], 
     CAST(NULL AS varchar(1)) AS [C25], 
     CAST(NULL AS varchar(1)) AS [C26], 
     CAST(NULL AS int) AS [C27], 
     [Extent9].[LookupId] AS [LookupId], 
     [Extent9].[MainId] AS [MainId2], 
     [Extent9].[MoreMoreData] AS [MoreMoreData], 
     [Extent9].[Field17] AS [Field171], 
     [Extent9].[Field16] AS [Field161], 
     [Extent9].[Field15] AS [Field151], 
     [Extent9].[Field14] AS [Field141], 
     [Extent9].[Field13] AS [Field131], 
     [Extent9].[Field12] AS [Field121], 
     [Extent9].[Field11] AS [Field111], 
     [Extent9].[Field1] AS [Field110], 
     [Extent9].[MainId] AS [MainId3] 
     FROM (SELECT TOP (1) [Extent8].[MainId] AS [MainId], [Extent8].[Field1] AS [Field1], [Extent8].[Field11] AS [Field11], [Extent8].[Field12] AS [Field12], [Extent8].[Field13] AS [Field13], [Extent8].[Field14] AS [Field14], [Extent8].[Field15] AS [Field15], [Extent8].[Field16] AS [Field16], [Extent8].[Field17] AS [Field17], [Extent8].[Field18] AS [Field18], [Extent8].[Field19] AS [Field19] 
      FROM [dbo].[MainTable] AS [Extent8] 
      WHERE 10 = [Extent8].[MainId]) AS [Limit4] 
     INNER JOIN [dbo].[MainTable_EvenMoreData] AS [Extent9] ON [Limit4].[MainId] = [Extent9].[MainId]) AS [UnionAll3] 
    ORDER BY [UnionAll3].[C3] ASC, [UnionAll3].[C1] ASC 
-- Executing at 2014-05-12 18:00:57 -04:00 
-- Completed in 39 ms with result: SqlDataReader 

risultato sql server

dbresult2

perché 8 righe quando 2 è sufficiente?

questo DB esempio, non è ottimizzato con indice e tale, ma qui è il piano di esecuzione

the plan

Idealmente mi piacerebbe produrre una query che sarebbe simile a questa mantenendo Entity Framework rilevamento delle modifiche dato che userò l'oggetto per aggiornare il database

SELECT  dbo.MainTable.MainId, dbo.MainTable.Field1, dbo.MainTable.Field11, dbo.MainTable.Field12, dbo.MainTable.Field13, dbo.MainTable.Field14, 
         dbo.MainTable.Field15, dbo.MainTable.Field16, dbo.MainTable.Field17, dbo.MainTable.Field18, dbo.MainTable.Field19, dbo.MainTable_EvenMoreData.LookupId, 
         dbo.MainTable_EvenMoreData.MainId AS Expr1, dbo.MainTable_EvenMoreData.MoreMoreData, dbo.MainTable_EvenMoreData.Field17 AS Expr2, 
         dbo.MainTable_EvenMoreData.Field16 AS Expr3, dbo.MainTable_EvenMoreData.Field15 AS Expr4, dbo.MainTable_EvenMoreData.Field14 AS Expr5, 
         dbo.MainTable_EvenMoreData.Field13 AS Expr6, dbo.MainTable_EvenMoreData.Field12 AS Expr7, dbo.MainTable_EvenMoreData.Field11 AS Expr8, 
         dbo.MainTable_EvenMoreData.Field1 AS Expr9, dbo.MainTable_LookupTable.MainId AS Expr10, dbo.MainTable_LookupTable.LookupId AS Expr11, 
         dbo.MainTable_MoreData.DataId, dbo.MainTable_MoreData.MainId AS Expr12, dbo.MainTable_MoreData.SomeData, dbo.MainTable_MoreData.Field1 AS Expr13, 
         dbo.MainTable_MoreData.Field11 AS Expr14, dbo.MainTable_MoreData.Field12 AS Expr15, dbo.MainTable_MoreData.Field13 AS Expr16, 
         dbo.MainTable_MoreData.Field14 AS Expr17, dbo.MainTable_MoreData.Field15 AS Expr18, dbo.MaintTable_DataLookup.MainId AS Expr19, 
         dbo.MaintTable_DataLookup.Data, dbo.MaintTable_DataLookup.Field1 AS Expr20, dbo.MaintTable_DataLookup.Field11 AS Expr21, 
         dbo.MaintTable_DataLookup.Field12 AS Expr22, dbo.MaintTable_DataLookup.Field14 AS Expr23, dbo.MaintTable_DataLookup.Field15 AS Expr24, 
         dbo.MaintTable_DataLookup.Field13 AS Expr25 
FROM   dbo.MainTable LEFT OUTER JOIN 
         dbo.MainTable_EvenMoreData ON dbo.MainTable.MainId = dbo.MainTable_EvenMoreData.MainId LEFT OUTER JOIN 
         dbo.MainTable_LookupTable ON dbo.MainTable.MainId = dbo.MainTable_LookupTable.MainId LEFT OUTER JOIN 
         dbo.MainTable_MoreData ON dbo.MainTable.MainId = dbo.MainTable_MoreData.MainId LEFT OUTER JOIN 
         dbo.MaintTable_DataLookup ON dbo.MainTable.MainId = dbo.MaintTable_DataLookup.MainId 
WHERE dbo.MainTable.MainId = 10 
+0

SO, dov'è la query hugh;)? – TomTom

+1

Sì, questo è normale. Ti dà fastidio? Questo è un codice generato, qualcosa che raramente si vuole anche guardare a –

+1

@JeroenVannevel, quando vedo che ogni unione fa un join sulla tabella principale con la stessa clausola where again e ... non sono un esperto sql ma questo sembra inefficiente. questo è un test di esempio. sul modello reale la query è ancora più grande e restituisce migliaia di righe mentre se usavo la normale query di join a sinistra sarebbe inferiore a 50 righe – Fredou

risposta

3

così dopo un paio d'ore a giocare in giro, ho fatto un po 'di bilanciamento del carico/esecuzione del piano/statistica a mq l server con un semplice join sinistro e l'enorme query che fa il framework di entità.

sembra che la struttura dell'entità vinca con un grande margine.

Ho intenzione di implementare la soluzione .include().

+0

btw, come sei riuscito ad accettare la tua risposta alla tua domanda? – adminSoftDK

2

Sì, questo è normale. Entity Framework sta prendendo il tuo modello relazionale (di solito gerarchico) e sta provando a produrre una query che produrrà tutti i dati necessari in una tabella grande e piatta.

è possibile mantenere il comportamento di una inclusione mentre si utilizza più di una semplice unione sinistra per tutte loro?

Dipende da cosa intendi per "comportamento". Se intendi produrre una query SQL simile, allora no, non puoi. Ma bisogna chiedersi il motivo per cui ci si preoccupa: queste query potrebbero essere ottimizzate per SQL Server, ma non saranno ottimizzate per la leggibilità umana.

Se si intende che si desidera ottenere prestazioni migliori, ci sono strategie che è possibile utilizzare oltre a caricare tutti in un unico grande database di andata e ritorno.Una strategia che ho trovato a lavorare bene sta usando una nuova andata e ritorno per ogni rapporto, in questo modo:

var dataQuery = db.MainTables.Where(d => d.MainId == 10); 
var data = dataQuery.FirstOrDefault(); 
dataQuery.Select(x => x.MainTable_MoreData).ToList(); 
// etc. 

Ecco una semplice classe di utilità è possibile utilizzare per rendere questo meno noioso, soprattutto durante il caricamento dei dati da diversi relazioni profonde:

/// <summary> 
/// This class aids in loading a lot of related data in Entity Framework. 
/// <para> 
/// Typically Entity Framework either lets you load entities Eagerly or Lazily, 
/// but neither case handles things very well once you are adding many chained 
/// relationships. A more ideal approach in these cases is to load all of the 
/// entities you are going to need for a given relationship in a single round-trip, 
/// and do this once for every relationship you're interested in. 
/// That's what this class helps with. 
/// </para> 
/// <para> 
/// To use: simply create an EntityRelationshipLoader with the initial 
/// Entity-Framework-backed queryable that will be the basis of all the data 
/// you're going to be loading. Then for each entity you want to load in relationship 
/// to that original data type, call either <see cref="Include{TProp}"/> or 
/// <see cref="IncludeMany{TProp}"/>. The return value from calling these methods may 
/// be retained and used to include other property relationships based on the 
/// property that you just defined. Each call to any of these methods will produce a 
/// single round-trip. 
/// </para> 
/// <remarks> 
/// Remember that all actions on the loader, including its original 
/// construction, must be performed while the query's Entity Framework context 
/// is active. 
/// </remarks> 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class EntityRelationshipLoader<T> : IRelationshipPropertyBuilder<T> 
{ 
    private readonly IQueryable<T> _src; 

    public EntityRelationshipLoader(IQueryable<T> src) : this(src, true) 
    { 
    } 

    private EntityRelationshipLoader(IQueryable<T> src, bool evaluateSource) 
    { 
     _src = src; 
     if (evaluateSource) 
     { 
      LoadEntities(src); 
     } 
    } 

    public IRelationshipPropertyBuilder<TProp> IncludeMany<TProp>(Expression<Func<T, IEnumerable<TProp>>> navProp) 
    { 
     LoadEntities(_src.Select(navProp)); 
     return new EntityRelationshipLoader<TProp>(_src.SelectMany(navProp), false); 
    } 

    public IRelationshipPropertyBuilder<TProp> Include<TProp>(Expression<Func<T, TProp>> navProp) 
    { 
     return new EntityRelationshipLoader<TProp>(_src.Select(navProp), true); 
    } 

    /// <summary> 
    /// Simple helper method to cause the given query to be executed, 
    /// thereby loading all the entities the query represents. 
    /// </summary> 
    /// <param name="query"></param> 
    private void LoadEntities<T1>(IQueryable<T1> query) 
    { 
#pragma warning disable 168 
     foreach (var item in query) 
     { 
     } 
#pragma warning restore 168 
    } 

Questo vi permetterà di dire:

var dataQuery = db.MainTables.Where(d => d.MainId == 10); 
var dataLoader = new EntityRelationshipLoader<MainTable>(dataQuery); 
dataLoader.Include(x => x.LookupTables); 
dataLoader.IncludeMany(x => x.MainTable_MoreData) 
    // Do you need to load MoreData's .LookupTables properties? 
    .Include(x => x.LookupTables); 
dataLoader.Include(x => x.MaintTable_DataLookup) 
dataLoader.Include(x => x.MainTable_EvenMoreData); 
var data = dataQuery.Single(); // Or ToList() if you need multiple of them. 
+0

ciò che non capisco è che la tabella piatta può essere enorme a seconda di quante righe sono presenti nelle tabelle figlio, guarda la mia ultima modifica (ultima immagine) se la tabella principale ha 30 campi con varchar (500) o più questo trasferirà tonnellate di dati senza motivo anche – Fredou

+0

@Fredou: è perché probabilmente stai usando * eager loading * che otterrà tutto ciò che riguarda la tua query la prima volta. Puoi anche usare * lazy loading * che interrogherà (approssimativamente) le cose che specifichi. http://msdn.microsoft.com/nl-be/data/jj574232#lazy –

+0

al momento quello che sto facendo è qualcosa come 'dbcontext.Entry (result) .Collection (x => x.MainTable_MoreData). Load (); 'che fa esattamente quello che hai suggerito, ma se mainTable diventa una raccolta (ToList() invece di FirstOrDefault()) e quindi sto facendo questo è un ciclo, questo potrebbe generare 4 query per righe maintable. che alla fine mi dà comunque una strana sensazione. – Fredou

Problemi correlati