2010-06-10 64 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