2014-04-06 119 views
0

顯示我的問題,我試圖解釋一個樣本:實體框架性能VS傳統ADO.Net

假設我有一個表UsersInfo這些列:

Id, UserName, Password, FName, LName, Gender, Birthday, 
HomeTel, Mobile, Fax, Email, LockStatus 

現在我想選擇LockStatus從這張桌子。在傳統模式下,我們取得這個查詢並將其發送給SqlCommand用於執行:

SELECT LockStatus FROM UsersInfo 

今天在使用實體框架,我們使用這個來自查詢:

var q = from r in new Data_DBEntities().UsersInfo 
     select new 
     { 
      r.LockStatus 
     }; 

實體SQL:

SELECT UsersInfo.LockStatus 
FROM Data_DBEntities.UsersInfo 

現在我啓動應用程序並使用SQL Server Profiler跟蹤它。如果我用的是第一種類型的查詢(傳統模式),我看到這樣的結果:

SELECT LockStatus FROM UsersInfo 

但是當我使用實體框架(LINQ ||實體SQL),在SQL Server探查表明,該結果:

SELECT 
[Extent1].[LockStatus] AS [LockStatus] 
FROM (SELECT 
     [UsersInfo].[Id] AS [Id], 
     [UsersInfo].[UserName] AS [UserName], 
     [UsersInfo].[Password] AS [Password], 
     [UsersInfo].[FName] AS [FName], 
     [UsersInfo].[LName] AS [LName], 
     [UsersInfo].[Gender] AS [Gender], 
     [UsersInfo].[Birthday] AS [Birthday], 
     [UsersInfo].[HomeTel] AS [HomeTel], 
     [UsersInfo].[Mobile] AS [Mobile], 
     [UsersInfo].[Fax] AS [Fax], 
     [UsersInfo].[Email] AS [Email], 
     [UsersInfo].[LockStatus] AS [LockStatus] 
     FROM [dbo].[UsersInfo] AS [UsersInfo]) AS [Extent1] 

我們可以看到EF在後臺選擇了所有的列。

現在我的問題是:我只想選擇一列,但EF選擇所有的列。如果我的桌子上有10萬條記錄,表現會非常糟糕!

也許說使用函數或存儲過程,但是當你想在不同的表中選擇不同的列時,這不是一個好主意。

您認爲如何?有什麼辦法嗎?

+0

你做錯了什麼。EF將查詢所有字段以生成對象 - 顯然。但是如果你在查詢中做了一個處理,那麼它就不會。 THAT說 - 這是我的幫助結束的地方,因爲我不熟悉LINQ sql語法,更喜歡我自己的函數式語法。我絕對沒有這個問題。 – TomTom

+0

雖然我明白查詢看起來很沉重,但我發現EF(現在在v6)與傳統的ADO.NET一樣快,並且我擁有數十萬行的表 - 提供查詢被正確書寫。如果您擔心**的表現**,您是否考慮過在表現**上進行測試**? –

回答

2

EF生成的查詢中有一個冗餘派生表,但最終只選擇一列。 SQL Server以及可能的任何主流RDBMS,在這種情況下只能物理地觸及單個列。不要擔心表現。這只是化妝品。

你沒有做錯任何事。沒有什麼可以爲你做的。

0

您在LINQ查詢中使用的語法強制重複選擇。

您的投影創建了2個獨立的對象。

var q = from r in new Data_DBEntities().UsersInfo創建一個新對象,然後將

select new 
    { 
     r.LockStatus 
    }; 

基礎上創建的第一個新的對象。您的第一部分中不需要使用關鍵字new

如果更改查詢

是:

var q = from r in Data_DBEntities().UsersInfo 
    select new 
    { 
     r.LockStatus 
    }; 

你會得到一個匿名的投影而無需進行額外的對象。 (並且沒有額外的字段以基於範圍。)

+0

我試試這個! 但它給我錯誤 – Jourmand

+0

@Jourmand:***什麼***錯誤!?!?!?記住:我們**不能**閱讀你的屏幕,也不能閱讀你的想法! –

+0

我的原始代碼是: 'var d = new Data_DBEntities(); 變種Q =從d.UsersInfo [R 選擇新 { r.LockStatus };' 但我的問題是:爲什麼EF選擇所有字段的,是正常?我使用LINQ,然後嘗試實體SQL,但兩種方式我看到相同的結果。 – Jourmand