[英]Entity Framework returning bad data
我有一個Entity Framework 6.1項目,它正在查詢SQL Server 2012數據庫表並返回錯誤的結果。
為了說明發生了什么,我創建了兩個應該具有完全相同結果的查詢。 表ProjectTable
有23列和20500行:
var test1 = db.ProjectTable
.GroupBy(t => t.ProjectOwner)
.Select(g => g.Key)
.ToArray();
var test2 = db.ProjectTable
.ToArray()
.GroupBy(t => t.ProjectOwner)
.Select(g => g.Key)
.ToArray();
查詢旨在獲取表中所有不同項目所有者的列表。 第一個查詢在SQL Server上執行繁重的工作,第二個查詢將整個表下載到內存中,然后在客戶端處理它。
第一個變量test1
的長度約為300個。 第二個變量test2
的長度為5。
以下是EF生成的原始SQL查詢:
-- test1
SELECT [Distinct1].[ProjectOwner] AS [ProjectOwner]
FROM ( SELECT DISTINCT
[Extent1].[ProjectOwner] AS [ProjectOwner]
FROM [dbo].[ProjectTable] as [Extent1]
) AS [Distinct1]
-- test2
SELECT Col1, Col2 ... ProjectOwner, ... Col23
FROM [dbo].[ProjectTable]
當我運行此查詢並分析返回的實體時,我注意到返回了完整的20500行,但ProjectOwner
列被僅有5個不同用戶中的一個覆蓋!
var test = db.ProjectTable.ToArray();
我想也許是SQL Server,所以我做了一個數據包跟蹤並在TDS上過濾。 隨機查看原始流我看到很多名稱不在5的列表中,所以我知道數據正在通過網絡正確發送。
如何查看EF獲取的原始數據? 有什么東西可能會搞亂緩存並拉出不正確的結果嗎?
如果我在SSMS或Visual Studio中運行查詢,則返回的列表是正確的。 只有EF才有這個問題。
好的,我添加了另一項測試,以確保我的理智得到控制。 我接受了test2
原始sql查詢並執行了以下操作:
var test3 = db.Database
.SqlQuery<ProjectTable>(@"SELECT Col1..Col23")
.ToArray()
.Select(t => t.ProjectOwner)
.Distict()
.ToArray();
我得到了正確的300個名字!
下載實體框架源並單步調試許多Enumerator
,我發現了這個問題。
在Shaper.HandleEntityAppendOnly
方法( 在此處找到 )中,在第187行調用Context.ObjectStateManager.FindEntityEntry
方法。 令我驚訝的是,返回了一個非null值! 等一下,不應該有任何緩存結果,因為我要返回所有行?!
那是我發現我的桌子沒有主鍵的時候!
在我的辯護中,該表實際上是我正在使用的視圖的緩存,我只是做了一個 SELECT * INTO CACHETABLE FROM USERVIEW
然后我查看實體框架認為哪個列是我的主鍵(他們稱之為單鍵),恰好它們所選擇的列只有...... 鼓請 ... 5個獨特的值!
當我看到EF生成的模型時,果然! 該列被指定為主鍵。 我將密鑰更改為相應的列,現在一切正常!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.