2008-12-22 95 views
6

我张贴这种question昨天晚上,这使我发现了一个巨大的问题Linq-to-Sql SubmitChanges不更新字段...为什么?

我在我的数据库名为单位小数列,只要我列的值设置为一个非零和的SubmitChanges用新值的列更新。如果我尝试将列的值设置为零,则SubmitChanges不会更新列。

data.Units = this.ReadProperty<decimal>(UnitsProperty); 
data.UnitPrice = this.ReadProperty<decimal>(UnitPriceProperty); 
data.Price = this.ReadProperty<decimal>(PriceProperty); 

我已经采取了看看DataContext的日志,我可以看到,与零值的字段不包含在查询中。即使我试图对Linq忽略它的改变进行硬编码。

data.Units = 0; 
data.UnitPrice = 0; 
data.Price = 0; 

不用说这是杀了我!任何想法为什么发生这种情况

解决方案

我想通了,我的问题与SO社会的帮助。我的问题是由于创建我的实体进行连接时造成的,因此列的默认值设置为零,因此当它尝试将值分配给零时... LinqToSql说嘿...没有任何更改,所以我没有更新价值。

我现在正在做什么...这只是为了工作如下:

ctx.DataContext.InvoiceItems.Attach(data, true); 

这似乎迫使所有的值写入自己的数据库。这现在工作。

+0

得到了你的类的任何部分方法,如OnCreated()或OnChanged()造成干扰?你有三重肠道检查你的模型吗? – 2008-12-22 13:08:28

+0

@Dave愚蠢的问题......但你说三重肠检查是什么意思? – mattruma 2008-12-22 13:12:16

回答

2

我想通了,我的问题与SO社会的帮助。我的问题是由于创建我的实体进行连接时造成的,因此列的默认值设置为零,因此当它尝试将值分配给零时... LinqToSql说嘿...没有任何更改,所以我没有更新价值。

我现在在做什么......只是使它工作如下:

ctx.DataContext.InvoiceItems.Attach(data, true); 

这似乎迫使所有值来写自己的数据库。这现在工作。

3

我试图重现这与下面的代码,但对我来说它的工作原理。

using (DataClasses1DataContext ctx = new DataClasses1DataContext()) 
{ 
    var obj = ctx.DecimalColumnTables.First(); 
    Debug.Assert(obj.B != 0); 
    obj.B = 0; 
    ctx.SubmitChanges(); 
} 

所以我认为在您的域中必须有一些特殊的东西导致这一点。我建议你用你的领域模型创建一个如此简单的repro,看看会发生什么。

的LINQ to SQL忽略更新到当前值,所以如果该字段已经为零,你可能看不到任何更新。

关:您使用的OR/M是的LINQ to SQL。 LINQ是.NET中查询功能的名称,但LINQ没有定义也没有实现任何更新逻辑。所以这个问题涉及到LINQ to SQL,而不是LINQ。

2

明显的问题,但你肯定列在DBML /映射文件映射?

此外 - 它是一个计算列? (即价格= >单位*单价)

2

一些更多信息...我想通了,我的问题...它更多的是缺乏对LinqToSql ...了解那里我做:

private void Child_Update(Invoice parent) 
{ 
     using (var ctx = Csla.Data.ContextManager 
      .GetManager(Database.ApplicationConnection, false)) 
     { 
      var data = new Gimli.Data.InvoiceItem() 
      { 
       InvoiceItemId = ReadProperty(InvoiceItemIdProperty) 
      }; 

      ctx.DataContext.InvoiceItems.Attach(data); 

      if (this.IsSelfDirty) 
      { 
       // Update properties 
      } 
    } 
} 

我认为这将加载原始值...会发生什么,它会创建一个具有默认值的新对象......空值,如小数点后的0,Guid.Empty中的uniqueidentifiers等等。

因此,当它更新属性时,它将单位看作0,并将其设置为零。那么LinqToSql并不认为这是一个改变,所以它不会更新该字段。所以我不得不做的是以下几点:

ctx.DataContext.InvoiceItems.Attach(data, true); 

现在所有的修改都是在update语句中生成的,不管是否真的有变化。这工作...似乎有点hackish!

0

我有这个问题,我看到的所有建议都没有应用或工作。

但我发现我犯了一个非常简单的错误!

当更新属性时,我实际上正在调用一个自定义的Set方法(因为还有其他事情需要改变以响应主要属性)。

经过数小时的头部划伤,我注意到我的Set方法更新了私有成员,而不是公共属性,即this._Walking = value;

我所要做的就是将其改为this.Walking = value;这一切都开始工作!

1

正确答案是因为许多指出使用连接,它接受一个布尔值参数,将其视为修改的,(让使用其他超载的错误,它只是将无法正常工作)的特殊超载:

ctx.DataContext.InvoiceItems.Attach(data, true); 

但请注意,您仍然可能需要在类型为“timestamp”的表中具有“版本”列。