2010-09-15 41 views
4

我是C#和.NET的新手,我剛開始學習LINQ to SQL,我喜歡它。但是..我發現這件事很令人討厭。由於「ForeignKeyReferenceAlreadyHasValueException」,實現lookUps非常複雜!沒有簡單的直接做法!我注意到,如果我刪除LINQ實體之間的所有關聯,「ForeignKeyReferenceAlreadyHasValueException」問題不再存在!我刨開發小型的WinForms數據庫應用程序,沒有100多個表...ForeignKeyReferenceAlreadyHasValueException當使用LINQ to SQL創建查找時

所以我的問題是:

我怎麼輸/風險,如果我使用LINQ2SQL但刪除所有LINQ實體之間的關聯並保持在數據庫中的關係?

+1

您可以發佈使用'ToLookup'的查詢之一併引發您提到的異常嗎?還要提及在查詢中使用哪個表/列是通過外鍵關係相關的。 – Timwi 2010-09-15 22:20:33

+0

當我編寫「lookups」時,我的意思是將LookUpEdit或ComboBox作爲獨立或InPlace編輯器放入某個GridView中。 (例如:設置DataSource,DisplayMember和ValueMember屬性與DataSet一起使用,但在LINQ2SQL中導入ForeignKeyReferenceAlreadyHasValueException) – EmirZ 2010-09-15 22:30:34

+0

什麼是LookupEdit? – recursive 2010-09-15 23:11:09

回答

5

基本上你將失去查詢的支持,延遲加載,智能感知等。例如,你不會有這樣的事情,如果你刪除用戶問題之間的關聯:

from u in context.Users 
where u.Questions.Count > 2 
select u; 

LINQ的意義在於爲您提供在C#代碼中實現關係數據庫模型所需的所有結構,使您能夠查詢該模型。如果你刪除了所有的關聯/關係,LINQ to SQL就失去了它的目的。

關於Exception你有:

如果關聯屬性是 分配你無法改變 外鍵字段了一個值,你必須 改變通過改變 的關聯屬性的關係。例如,使用 Northwind示例數據庫中的客戶和訂單。如果訂單上 「客戶」屬性是 分配可以不再 手動更改訂單的客戶ID 領域,因爲它必須的 客戶的PK匹配的值。但是,您可以直接更改「客戶」屬性 ,爲其分配新客戶 實例。此動作將自動更新 字段以匹配。馬特·沃倫(LINQ到SQL建築師)

這是你需要做什麼來解決你的問題:

LINQ to SQL ForeignKeyReferenceAlreadyHasValueException error

進行查找和LINQ,做到這一點:

LINQ, Lookups, ForeignKeyReferenceAlreadyHasValueException

使用此代碼例如綁定組合框時:

With cboCategory 
.DataSource = From Category In db.Categories Order By Category.Name 
       Select Category 
.DisplayMember = "Name" 
.ValueMember = "ID" don't set value member: http://tinyurl.com/d9etoy 
.DataBindings.Add(New Binding("SelectedItem", ItemBindingSource, "Category")) 
End With 
+0

請您詳細說明這最後的評論,也許給我一個例子(說客戶<->位置)以及如何綁定LookUpEdit(數據源,DisplayMember,ValueMember!?) – EmirZ 2010-09-15 22:50:20

+0

請參閱我提供給您的最後一個鏈接。這實際上是評論試圖說明的內容......您必須分配整個實體/對象,而不僅僅是Id屬性。 – 2010-09-15 22:52:41

+0

嗯,我已經有了,甚至在我問這個問題之前...我的問題是更多關於綁定LookUpEdit控件...我想我仍然沒有得到它。 – EmirZ 2010-09-15 22:57:11

1

你失去的當然是關係。通常的LINQ to SQL將自動填充有用的集合抽象的關係,例如:

var query = db.Orders.Where(o => o.Products.Count() > n); 
            ^^^^^^^^ 
          // You would lose this 

你將不得不給它的更迂迴的方式寫,例如

var query = db.Orders.Where(o => 
       db.OrderProducts.Count(p => p.ProductId == o.ProductId) > n); 
+0

我明白了你的觀點......但是當使用LookUpEdit之類的控件時,如何解決這個「ForeignKeyReferenceAlreadyHasValueException」(請閱讀上面的註釋)!儘管LINQ2SQL很容易使用,並且不能簡單地綁定LookUpEdit-s,並且總是要做一些即興創作,只是將這種簡單性帶走! – EmirZ 2010-09-15 22:45:57

4

您正在進行這些關係更改的錯誤方式。如果你有一個連接到它作爲成員的客戶對象的訂單對象,您可以查看客戶信息,像這樣:

var order = db.Orders.Single(x => x.ID == 40); 
var cusName = order.Customer.GetFullCustomerName(); 

然而,如果你需要改變客戶對於訂單在數據庫中,你可以只需將Order.CustomerID字段設置爲新的ID即可。這將拋出ForeignKeyReferenceAlreadyHasValueException錯誤。

// wrong way... 
order.CustomerID = 45; // id of the new customer 
// BOOOOM goes the error here. 

// right way... 
order.Customer = db.Customer.Single(x => x.ID == 45); 

db.SubmitChanges(); 

換句話說,一旦你從數據庫中拉下Order.Customer,你不能手動只是通過改變Orders表該行的外鍵更改相關的客戶。您必須將order.Customer成員設置爲另一個實際的Customer對象,然後以這種方式將更改返回到數據庫。