Linq-to-Sql SubmitChanges没有更新字段……为什么?
我昨天晚上发布了这个问题 ,这让我发现了一个很大的问题!
我的数据库中有一个名为Units的十进制列,只要我将列的值设置为NON ZERO,并使用新值SubmitChanges列更新。 如果我尝试将列的值设置为ZERO,则SubmitChanges不会更新列。
data.Units = this.ReadProperty(UnitsProperty); data.UnitPrice = this.ReadProperty(UnitPriceProperty); data.Price = this.ReadProperty(PriceProperty);
我已经看了一下DataContext日志,我可以看到查询中不包含具有ZERO值的字段。 即使我试图对代码进行硬编码,Linq也会忽略它。
data.Units = 0; data.UnitPrice = 0; data.Price = 0;
不用说这是杀了我! 任何想法为什么会这样?
解
我在SO社区的帮助下想出了我的问题。 我的问题是由于我创建我的实体附加时的事实,列的默认值设置为零,所以当它试图将值分配给零时… LinqToSql说嘿……没有改变,所以我没有更新价值。
我现在在做什么……只是为了让它发挥作用如下:
ctx.DataContext.InvoiceItems.Attach(data, true);
这似乎迫使所有值自己写入数据库。 这适用于现在。
我试图用下面的代码重现这个,但对我来说它是有效的。
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中查询function的名称,但LINQ不定义也不实现任何更新逻辑。 所以这个问题与LINQ to SQL有关,而不是LINQ。
明显的问题,但你确定列是在dbml / mapping文件中映射的吗?
另外 – 它是一个计算列吗? (即价格=>单位* unitprice)
我在SO社区的帮助下想出了我的问题。 我的问题是由于我创建我的实体附加时的事实,列的默认值设置为零,所以当它试图将值分配给零时… LinqToSql说嘿……没有改变,所以我没有更新价值。
我现在在做什么……只是为了让它发挥作用如下:
ctx.DataContext.InvoiceItems.Attach(data, true);
这似乎迫使所有值自己写入数据库。 这适用于现在。
更多信息……我想出了我的问题……更多的是对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,uniqueidentifiers为Guid.Empty等等。
因此,当它更新属性时,它会将Units视为0,并将其设置为零。 好吧,LinqToSql不会将此识别为更改,因此它不会更新该字段。 所以我必须做的是以下内容:
ctx.DataContext.InvoiceItems.Attach(data, true);
现在,无论是否真的发生了更改,都会在update语句中生成所有修改。 这工作……似乎有点hackish!
正确的答案是许多人指出使用Attach的特殊重载,它接受一个布尔参数来将其视为已修改,(使用另一个重载的错误,它根本不起作用):
ctx.DataContext.InvoiceItems.Attach(data, true);
但请注意,您仍可能需要在“timestamp”类型的表中包含“Version”列。
我有这个问题,我看到的所有建议都没有适用或工作。
但我发现我犯了一个非常简单的错误!
更新属性时,我实际上调用了一个自定义Set方法(因为还有其他一些东西需要更改以响应相关的主要属性)。
经过数小时的头部刮擦,我注意到我的Set方法正在更新私有成员而不是公共属性,即this._Walking = value;
我所要做的就是将其改为this.Walking = value; 这一切都开始奏效了!
- Winforms数据绑定:可以使用TypeConverter而不是Format / Parse事件吗?
- 具有Queryover的动态Where条件
- 使用NHibernate映射通用类
- 是否存在由子Thread对象自动inheritance的可编程数据?
- 只读字典 – 多个线程调用.ContainsKey方法
- VS 2010与VS 2008中的optionalAttribute(用于声明可选参数)行为的差异
- 为什么Silverlight TextBox使用\ r代替换行而不是Environment.Newline(\ r \ n)?
- 请解释.NET代表
- 是否可以使用TagLibSharp从MP3文件中删除Lyrics3v2标签?