2013-02-14 33 views
0

雖然在使用LINQ 2 SQL我已經跑了與方式有問題,其中的LINQ 2 SQL生成SQL語句在繼承映射派生類型定義的示例應用程序實現了AdventureWorks分貝在我的DBML中。LINQ的2 SQL - 繼承多個SQL語句

我在我的DBML,Person和PersonPhone(一個人到許多PersonPhones)兩個實體WITHOUT定義的任何繼承映射(人將在稍後的例子的繼承基類)。如果我再運行下面的LINQ的發言中,我注意到,雖然做的走線,預期會生成以下SQL:

void Main() 
{ 
this.DeferredLoadingEnabled = false; 

DataLoadOptions dlo = new DataLoadOptions(); 
dlo.LoadWith<Person>(n => n.PersonPhones); 
this.LoadOptions = dlo; 

Person person = this.Persons.SingleOrDefault(n => n.BusinessEntityID == 291); 
person.PersonPhones.Dump(); 
} 

DECLARE @p0 Int = 291 
SELECT [t0].[BusinessEntityID], [t0].[PersonType], [t0].[NameStyle], [t0].[Title], [t0].[FirstName], [t0].[MiddleName], [t0].[LastName], [t0].[Suffix], [t0].[EmailPromotion], [t0].[AdditionalContactInfo], [t0].[Demographics], [t0].[rowguid], [t0].[ModifiedDate], [t1].[BusinessEntityID] AS [BusinessEntityID2], [t1].[PhoneNumber], [t1].[PhoneNumberTypeID], [t1].[ModifiedDate] AS [ModifiedDate2], (
    SELECT COUNT(*) 
    FROM [Person].[PersonPhone] AS [t2] 
    WHERE [t2].[BusinessEntityID] = [t0].[BusinessEntityID] 
    ) AS [value] 
FROM [Person].[Person] AS [t0] 
LEFT OUTER JOIN [Person].[PersonPhone] AS [t1] ON [t1].[BusinessEntityID] = [t0].[BusinessEntityID] 
WHERE [t0].[BusinessEntityID] = @p0 
ORDER BY [t0].[BusinessEntityID], [t1].[PhoneNumber], [t1].[PhoneNumberTypeID] 

的結果是,SQL在單個語句生成。請忽略這可能是效率低下的SQL這一事實,我要說的是,它只是在一個聲明中運行。

但是,如果我包括我的DBML繼承映射信息,並定義一個名爲StoreContact一個新的實體類型(從Person派生),然後運行完全相同的查詢其實我得到不同的結果如下圖所示。在這兩個SQL語句實際上運行。

DECLARE @p0 Int = 291 
SELECT [t0].[PersonType], [t0].[BusinessEntityID], [t0].[NameStyle], [t0].[Title], [t0].[FirstName], [t0].[MiddleName], [t0].[LastName], [t0].[Suffix], [t0].[EmailPromotion], [t0].[AdditionalContactInfo], [t0].[Demographics], [t0].[rowguid], [t0].[ModifiedDate] 
FROM [Person].[Person] AS [t0] 
WHERE [t0].[BusinessEntityID] = @p0 
GO 

DECLARE @x1 Int = 291 
SELECT [t0].[BusinessEntityID], [t0].[PhoneNumber], [t0].[PhoneNumberTypeID], [t0].[ModifiedDate] 
FROM [Person].[PersonPhone] AS [t0] 
WHERE [t0].[BusinessEntityID] = @x1 

這在一定程度上有問題,這將相當顯着降低我們的應用程序的速度在LINQ的2 SQL需要進行重複調用數據庫中實現繼承特性的情況下。看起來有一個OOP模型是有代價的。

是否有這個問題,使SQL運行在單個語句解決方法?

+0

我應該表達的一點是,在此示例中,我在繼承映射更改之前和之後都使用了SAME linq語句。 – user978139 2013-02-14 11:03:02

+0

爲什麼第一個SQL會計數? L2S插入這個可怕的聚合體還是來自你的代碼? – usr 2013-02-14 11:16:12

+0

因爲'query'沒有針對數據庫運行,所以直到執行以下代碼行:ac.PersonPhones.Count.Dump(),因此它會根據linq語句將它轉換爲最合適的SQL語句。這只是它在一個SQL語句中執行linq查詢的一個例子,我試圖用繼承來實現它,它可能產生了低效的SQL並不重要,因爲我可以重寫我的Linq查詢爲了做點數更有效率。 – user978139 2013-02-14 11:52:03

回答

0

可惜不是我要找的答案,但升級到實體框架將解決這個問題,同時保持了繼承。

如果我運行下面的EF等效查詢:

void Main() 
{ 
    StoreContact person =(StoreContact)this.People.Include("PersonPhones").SingleOrDefault(n => n.BusinessEntityID == 291); 
    person.PersonPhones.Dump(); 
} 

我碰到下面的SQL結果:

SELECT 
[Project2].[BusinessEntityID] AS [BusinessEntityID], 
[Project2].[C1] AS [C1], 
[Project2].[NameStyle] AS [NameStyle], 
[Project2].[Title] AS [Title], 
[Project2].[FirstName] AS [FirstName], 
[Project2].[MiddleName] AS [MiddleName], 
[Project2].[LastName] AS [LastName], 
[Project2].[Suffix] AS [Suffix], 
[Project2].[EmailPromotion] AS [EmailPromotion], 
[Project2].[AdditionalContactInfo] AS [AdditionalContactInfo], 
[Project2].[Demographics] AS [Demographics], 
[Project2].[rowguid] AS [rowguid], 
[Project2].[ModifiedDate] AS [ModifiedDate], 
[Project2].[C2] AS [C2], 
[Project2].[BusinessEntityID1] AS [BusinessEntityID1], 
[Project2].[PhoneNumber] AS [PhoneNumber], 
[Project2].[PhoneNumberTypeID] AS [PhoneNumberTypeID], 
[Project2].[ModifiedDate1] AS [ModifiedDate1] 
FROM (SELECT 
    [Limit1].[BusinessEntityID] AS [BusinessEntityID], 
    [Limit1].[NameStyle] AS [NameStyle], 
    [Limit1].[Title] AS [Title], 
    [Limit1].[FirstName] AS [FirstName], 
    [Limit1].[MiddleName] AS [MiddleName], 
    [Limit1].[LastName] AS [LastName], 
    [Limit1].[Suffix] AS [Suffix], 
    [Limit1].[EmailPromotion] AS [EmailPromotion], 
    [Limit1].[AdditionalContactInfo] AS [AdditionalContactInfo], 
    [Limit1].[Demographics] AS [Demographics], 
    [Limit1].[rowguid] AS [rowguid], 
    [Limit1].[ModifiedDate] AS [ModifiedDate], 
    [Limit1].[C1] AS [C1], 
    [Extent2].[BusinessEntityID] AS [BusinessEntityID1], 
    [Extent2].[PhoneNumber] AS [PhoneNumber], 
    [Extent2].[PhoneNumberTypeID] AS [PhoneNumberTypeID], 
    [Extent2].[ModifiedDate] AS [ModifiedDate1], 
    CASE WHEN ([Extent2].[BusinessEntityID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2] 
    FROM (SELECT TOP (2) 
     [Extent1].[BusinessEntityID] AS [BusinessEntityID], 
     [Extent1].[NameStyle] AS [NameStyle], 
     [Extent1].[Title] AS [Title], 
     [Extent1].[FirstName] AS [FirstName], 
     [Extent1].[MiddleName] AS [MiddleName], 
     [Extent1].[LastName] AS [LastName], 
     [Extent1].[Suffix] AS [Suffix], 
     [Extent1].[EmailPromotion] AS [EmailPromotion], 
     [Extent1].[AdditionalContactInfo] AS [AdditionalContactInfo], 
     [Extent1].[Demographics] AS [Demographics], 
     [Extent1].[rowguid] AS [rowguid], 
     [Extent1].[ModifiedDate] AS [ModifiedDate], 
     '0X0X' AS [C1] 
     FROM [Person].[Person] AS [Extent1] 
     WHERE 291 = [Extent1].[BusinessEntityID]) AS [Limit1] 
    LEFT OUTER JOIN [Person].[PersonPhone] AS [Extent2] ON [Limit1].[BusinessEntityID] = [Extent2].[BusinessEntityID] 
) AS [Project2] 
ORDER BY [Project2].[BusinessEntityID] ASC, [Project2].[C2] ASC 

的SQL語句返回一個查詢中的結果。

的原因,這是不是我要找的答案是,從LINQ的過渡到SQL實體框架現有應用程序是一個相當大的一步。