2009-06-16 55 views
12

將telerik RadGrid和普通香草ASP.NET GridView綁定到以下LINQ to實體查詢的結果時遇到問題。在這兩種情況下,網格都包含正確的行數,但只有第一行的數據在所有其他行中重複。我直接將這個代碼的返回值分配給網格上的DataSource屬性。LINQ to Entities綁定數據時出現重複行

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; 

更多

  1. 通過LINQ發送到SQL Server的查詢工作。
  2. 在返回它們之前迭代LINQ查詢結果導致相同的重複。
  3. 在綁定之前迭代調用方法中的LINQ結果會導致相同的重複。

UPDATE: 上非常符合邏輯和裝修建議基於從馬克下方碎石,我發現EF設計已在實體鍵爲我的實體類做了一個非常沒有受過教育的猜測,第一場在其部門的名單中,其中所有其他記錄中只有大約7個條目共享。

這確實是重複的原因。如果只有我可以更改或刪除實體關鍵字,但是這位擁有Etch-a-Sketch所有業務邏輯的EF設計師非常忠於重複它的關鍵選擇,同時嘲笑我鎖在外面,請求更改關鍵字。

+0

您確定該表不包含重複項嗎?該查詢是正確的。 – 2009-06-17 06:17:10

+0

@亞歷山大,是的,我確定。同一視圖上的普通DataTable查詢會導致網格正確綁定。 – ProfK 2009-06-17 08:28:20

+0

請顯示更多代碼。工作和問題。 – 2009-06-19 05:03:38

回答

30

它在我看來像你有一個borked主鍵。 LINQ-to-SQL和EF的「身份管理」方面意味着,只要它看到相同對象類型的相同主鍵值,就有義務讓您回到同一個實例。

例如,給出的數據:如認爲id

id  | name  | ... 
-------+------------+------ 
1  | Fred  | ... 
2  | Barney  | ... 
1  | Wilma  | ... 
1  | Betty  | ... 

然後是主鍵遍歷從LINQ的對象時,它是被迫給你「弗雷德」,「巴尼「,」弗雷德「,」弗雷德「。本質上,當它再次看到id 1時,它甚至不會查看其他列 - 它只是從身份緩存中提取id 1,併爲您提供與之前提供的Fred實例相同的實例。如果它認爲id是一個主鍵,它會將每一行視爲一個單獨的對象(以及如果它與另一個記錄在一個字段中具有相同的值 - 這不完全不尋常)。

我會建議檢查您標記爲主鍵的任何字段(在您的DBML/EDM模型中)是否每行都是唯一的。在上面的例子中,id列顯然不代表唯一的標識符,因此不適合作爲主鍵。只需在LINQ-to-SQL/EF設計器中對其進行取消標記即可。


更新:特別是看在設計師的各種屬性中的「實體鍵」屬性 - 特別是如果你查詢視圖。檢查對於合適的列(即使行唯一的那些)的「實體密鑰」僅被設置爲真。如果設置不正確,請將其設置爲false。這也是可見的黃色鑰匙圖標 - 這應該只出現在真正是記錄的唯一標識符的東西上。

1

如果您將鏈接查詢包裝在括號中並使用.Distinct()擴展名?

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).Distinct(); 
} 
0

你的工作和打破的查詢之間的一個區別是orderby子句。我在LINQ中找到一個documented bug的實體,可能有其他的實體。

嘗試從破損的查詢中刪除orderby,看看是否仍然有重複。

另一個區別是where子句中的OR。嘗試只使用第一部分[where dp.LastName.StartsWith(searchTerm)],看看你是否仍然有重複。

0

我遇到了同樣的問題,並通過解決方法解決了這個問題。我在這裏發佈它,因爲它可能有助於其他人來到這裏。

,而不是選擇DP,使用

select new <ObjectName> 
{ 
a = v.a 
b = v.b 
}. 

這將不會返回重複。