2010-06-10 126 views
7

我在將linq更新爲sql實體時遇到了一些麻煩。 出於某種原因,我可以更新我的item實體的每個字段,除名稱Linq to SQL - 未能更新

這裏有兩個簡單的測試中,我寫道:

[TestMethod] 
     public void TestUpdateName() { 
      using (var context = new SimoneDataContext()) { 
       Item item = context.Items.First(); 

       if (item != null) { 
        item.Name = "My New Name"; 
        context.SubmitChanges(); 
       } 
      } 
     } 

     [TestMethod] 
     public void TestUpdateMPN() { 
      using (var context = new SimoneDataContext()) { 
       Item item = context.Items.First(); 

       if (item != null) { 
        item.MPN = "My New MPN"; 
        context.SubmitChanges(); 
       } 
      } 
     } 

不幸的是,TestUpdateName()失敗,出現以下錯誤: System.Data.SqlClient.SqlException: Incorrect syntax near the keyword 'WHERE'..

而這裏的輸出SQL:

UPDATE [dbo].[Items] SET WHERE ([Id] = @p0) AND ([CategoryId] = @p1) AND ([MPN] = @p2) AND ([Height] = @p3) AND ([Width] = @p4) AND ([Weight] = @p5) AND ([Length] = @p6) AND ([AdministrativeCost] = @p7) -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p2: Input VarChar (Size = 10; Prec = 0; Scale = 0) [My New MPN] -- @p3: Input Decimal (Size = 0; Prec = 5; Scale = 3) [30.000] -- @p4: Input Decimal (Size = 0; Prec = 5; Scale = 3) [10.000] -- @p5: Input Decimal (Size = 0; Prec = 5; Scale = 3) [40.000] -- @p6: Input Decimal (Size = 0; Prec = 5; Scale = 3) [30.000] -- @p7: Input Money (Size = 0; Prec = 19; Scale = 4) [350.0000] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.4926

由於你可以看到,沒有更新正在產生(SET是空的......) 我不知道爲什麼會發生這種情況。

而且已經預先...是的,表Item有一個PK(Id)。 謝謝提前!

更新: 看來,錯誤是由覆蓋GetHashcode()引起的。 這是我目前實施:

return string.Format("{0}|{1}|{2}|{3}", Name, Id, UPC, AdministrativeCost).GetHashCode();

+0

如果修改名稱和一個其他財產發生了什麼?它是更新兩者還是僅更新其他屬性?在生成的代碼中,還有名爲「PropertyChanged」事件的setter?我不認爲DataContext認爲它是一個改變,除非事件被解僱。 – 2010-06-10 17:58:20

+0

如果我修改名稱和另一個屬性,則只更改其他屬性。 – 2010-06-10 18:05:58

回答

12

聽起來像你的DBML可能不同步。您應該刪除這些表並重新添加它們並嘗試再次運行它。

只需手動刪除Items表並重新添加它。

編輯:根據您的編輯,您應該查看以下關於GetHashCode的線索。

http://social.msdn.microsoft.com/forums/en-US/linqtosql/thread/6cc6c226-f718-4b22-baad-dba709afe74b/

.Net rules claim that GetHashCode() and Equals() must always be implemented in tandem. Two objects that are equal must have the same hash code.

Also, the combination of GetHashCode() + Equals() forms the entity's concept of identity. If you make it based on field values (other than PK) then the identity changes as you change the fields. This is bad if L2S must lookup other info in a dictionary based on the entity's identity, and especially if L2S needs to find an entity in its identity cache!

Advice: don't change the identity of an entity. L2S expects it to be based on the object's natural (address based) identity.

+0

剛剛刪除了表格手動,它不起作用。 我也嘗試使用Hugati工具再次同步它,並且出現同樣的錯誤。 – 2010-06-10 17:54:33

+0

@Isaac TestUpdateMPN是否正常工作,TestUpdateName是否失敗?當表的dbml定義與模式不匹配時,似乎發生此錯誤。 – Kelsey 2010-06-10 17:57:26

+0

爲GetHashCode()的東西+1。原來是我的問題。嘗試更改由GetHashCode()覆蓋的字段。 – tandrewnichols 2012-12-12 03:17:40

0

看來,正在生成SQL不包括SET條款(請注意,有SET之後沒有[Name] = @pXX)的內容。是否在dbml設計器中正確設置了實體字段的所有屬性(數據類型,大小等)?

+0

我注意到了這一點,我在一分鐘前編輯了這篇文章。 DBML上的屬性似乎是正確的。 我使用Hugati DBML工具來維護我的DBML模式與數據庫同步。 感謝您的回覆。 – 2010-06-10 17:51:03

+0

@Isaac:最新版本仍然反映了這個問題(它說'UPDATE [dbo]。[Items] SET WHERE ...')。 L2S不會生成要更新的列表以及與它們相關的值(您希望它會說'UPDATE [dbo]。[Items] SET [Name] = @ p0 WHERE ...'或類似的東西)。 – 2010-06-10 17:58:14