簡體   English   中英

實體框架在SQL查詢中不使用JOIN

[英]Entity framework doesn't use JOIN in SQL queries

我為從Defect實例獲取Invoice實例的一對多關系編寫了一些代碼。

mydbEntities ef = new mydbEntities (); //mydbEntities is derived from DbContext
ef.Database.Log = s => System.Diagnostics.Debug.WriteLine (s);
Invoice inv = ef.Defects.Where (i => i.Id == 5).SingleOrDefault ().Invoice;

這是EDM圖的一部分:

EDM圖

我很好奇為什么它不調用INNER JOIN,而是執行2個SQL查詢。 在我正在閱讀的書中(“掌握實體框架”),在相同的情況下,調用了INNER JOIN。

調試輸出:

SELECT TOP (2) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[PositionId] AS [PositionId], 
    [Extent1].[InvoiceId] AS [InvoiceId], 
    [Extent1].[Count] AS [Count], 
    [Extent1].[Reason] AS [Reason]
    FROM [dbo].[Defect] AS [Extent1]
    WHERE 5 = [Extent1].[Id]


-- Executing at 6/21/2015 11:21:02 AM +05:00

-- Completed in 1 ms with result: SqlDataReader



Closed connection at 6/21/2015 11:21:02 AM +05:00

Opened connection at 6/21/2015 11:21:02 AM +05:00

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Number] AS [Number], 
    [Extent1].[InvoiceDate] AS [InvoiceDate]
    FROM [dbo].[Invoice] AS [Extent1]
    WHERE [Extent1].[Id] = @EntityKeyValue1


-- EntityKeyValue1: '1' (Type = Int32, IsNullable = false)

-- Executing at 6/21/2015 11:21:02 AM +05:00

-- Completed in 0 ms with result: SqlDataReader



Closed connection at 6/21/2015 11:21:02 AM +05:00

還有一個問題:使用INNER JOIN對1進行2個查詢如何影響具有大型數據庫的高負載應用程序的性能。

您應該添加.Include(d => d.Invoice)調用。 嘗試這個:

    mydbEntities ef = new mydbEntities (); //mydbEntities is derived from DbContext
    ef.Database.Log = s => System.Diagnostics.Debug.WriteLine (s);
    Invoice inv = ef.Defects
        .Include(d => d.Invoice)
        .Where (i => i.Id == 5)
        .SingleOrDefault()
        .Invoice;

EntityFramework(以及大多數其他的Linq to Sql工具)只是懶惰到一定程度。 有一組強制查詢運行的方法。 一些例子是:

  • Single / SingleSingleOrDefault
  • First / FirstOrDefault
  • ToList
  • ToArray

我使用的技巧是,這些方法中的每一個都具有返回Task<T>的異步版本。 因此,如果IDE中的自動完成功能包括SingleOrDefaultAsync則很明顯SingleOrDefault會導致查詢運行。

請注意,Linq to Objects也會發生相同的行為。 每個ToList,Single等都是eager方法,而返回IEnumerable的方法是惰性的,並在第一個eager操作中執行。

為了回答您的問題, Include方法通過返回聯接數據來解決此問題。 如果正確使用它可以提高性能。

在您的示例中,您將從對象中獲取Invoice屬性,因此正確的調用將是使用.Include(d => d.Invoice).Include("Invoice") 這兩個都告訴EF在第一個查詢中拉回Invoice信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM