使用 LINQ to Entities 進行數據綁定時出現重複行
我在將 Telerik RadGrid 和普通的 ASP.NET GridView 綁定到以下 LINQ 到實體查詢的結果時遇到問題。在這兩種情況下,網格都包含正確的行數,但只有前幾行的數據在所有其他行中重複。我直接將此程式碼的返回值分配給網格上的 DataSource 屬性。
public IEnumerable<DirectoryPersonEntry> FindPersons(string searchTerm) { DirectoryEntities dents = new DirectoryEntities(); return from dp in dents.DirectoryPersonEntrySet where dp.LastName.StartsWith(searchTerm) || dp.Extension.StartsWith(searchTerm) orderby dp.LastName, dp.Extension select dp; }**添加:**這是可以使用的備用純 ADO.NET 程式碼:
DataTable ret = new DataTable(); using (SqlConnection sqn = new SqlConnection(ConfigurationManager.ConnectionStrings["WaveAdo"].ConnectionString)) { SqlDataAdapter adap = new SqlDataAdapter("select * from DirectoryPersonList where LastName like '" + searchTerm + "%' order by LastName ", sqn); sqn.Open(); adap.Fill(ret); } return ret;更多:
- LINQ 發送到 SQL Server 的查詢有效。
- 在返回它們之前迭代 LINQ 查詢結果會導致相同的重複。
- 在綁定之前迭代 LINQ 會導致呼叫方法產生相同的重複。
更新:根據下面Marc Gravel非常合乎邏輯和合適的建議,我發現 EF 設計者對我的實體類的實體鍵做出了非常未經教育的猜測,它的欄位列表中的第一個欄位,部門,其中只有大約七個條目在所有其他記錄中共享。
這確實是重複的原因。如果我可以更改或刪除實體密鑰,但這位具有 Etch-a-Sketch 的所有業務邏輯的 EF 設計師令人欽佩地致力於重複其遲緩的密鑰選擇,同時嘲笑我被鎖在外面乞求更改密鑰。
在我看來,您的主鍵很糟糕。LINQ-to-SQL 和 EF 的“身份管理”方面意味著當它看到相同對像類型的相同主鍵值時,它必須返回相同的實例。
例如,給定數據:
id | name | ... -------+------------+------ 1 | Fred | ... 2 | Barney | ... 1 | Wilma | ... 1 | Betty | ...然後,如果它在從 LINQ 迭代對象時認為
id是主鍵,它會被迫給你“Fred”、“Barney”、“Fred”、“Fred”。本質上,當它再次看到id1 時,它甚至不會查看其他列 - 它只是id從身份記憶體中獲取具有 1 的實例 - 並為您提供它之前提供給您的同一個 Fred 實例。如果它認為不是id主鍵,它會將每一行視為一個單獨的對象(如果它在一個欄位中與另一條記錄具有相同的值怎麼辦 - 這並不完全不尋常)。我建議檢查您標記為主鍵的任何欄位(在您的 DBML/EDM 模型中)是否真的每行都是唯一的。在上述情況下,該
id列顯然不代表唯一標識符,因此不適合作為主鍵。只需在 LINQ-to-SQL / EF 設計器中取消標記即可。更新:特別是查看設計器中各種屬性的“實體鍵”屬性——尤其是在查詢視圖時。檢查“實體鍵”是否僅針對合適的列(即使行唯一的那些)設置為 true。如果設置不正確,請將其設置為 false。這也顯示為黃色鑰匙圖示 - 這應該只出現在真正是記錄唯一標識符的事物上。