C# Linq到Sql提交更改未更新字段。。。为什么?

C# Linq到Sql提交更改未更新字段。。。为什么?,c#,.net,linq,linq-to-sql,C#,.net,Linq,Linq To Sql,我昨天晚上发布了这篇文章,这让我发现了一个巨大的问题 我的数据库中有一个称为Units的十进制列,每当我将该列的值设置为非零,并提交更改时,该列将使用新值进行更新。如果我尝试将列的值设置为零,SubmitChanges不会更新列 data.Units = this.ReadProperty<decimal>(UnitsProperty); data.UnitPrice = this.ReadProperty<decimal>(UnitPriceProperty); dat

我昨天晚上发布了这篇文章,这让我发现了一个巨大的问题

我的数据库中有一个称为Units的十进制列,每当我将该列的值设置为非零,并提交更改时,该列将使用新值进行更新。如果我尝试将列的值设置为零,SubmitChanges不会更新列

data.Units = this.ReadProperty<decimal>(UnitsProperty);
data.UnitPrice = this.ReadProperty<decimal>(UnitPriceProperty);
data.Price = this.ReadProperty<decimal>(PriceProperty);
不用说,这简直要了我的命!你知道为什么会这样吗

解决方案


在SO社区的帮助下,我解决了我的问题。我的问题是由以下事实引起的:当我创建要附加的实体时,列的默认值设置为零,因此当它尝试将值指定为零时。。。LinqToSql说嘿。。。没有更改,因此我不更新该值

我现在所做的。。。要使其发挥作用,需要以下几点:

ctx.DataContext.InvoiceItems.Attach(data, true);
ctx.DataContext.InvoiceItems.Attach(data, true);
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();
}
所以我认为在你的领域里一定有什么特别的东西导致了这一点。我建议你用你的领域模型创建一个如此简单的复制,看看会发生什么

LINQ to SQL忽略对当前值的更新,因此,如果该字段已为零,则可能看不到任何更新


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

这是一个明显的问题,但您确定列映射到了dbml/mapping文件中吗


还有-它是计算列吗?(即价格=>单位*单价)

在SO社区的帮助下,我解决了我的问题。我的问题是由以下事实引起的:当我创建要附加的实体时,列的默认值设置为零,因此当它尝试将值指定为零时。。。LinqToSql说嘿。。。没有更改,因此我不更新该值

我现在所做的。。。要使其发挥作用,需要以下几点:

ctx.DataContext.InvoiceItems.Attach(data, true);
ctx.DataContext.InvoiceItems.Attach(data, true);
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表示小数,Guid.empty表示唯一标识符等

因此,当它更新属性时,它会将单位视为0,并将其设置为0。LinqToSql不认为这是一个更改,因此它不会更新字段。因此,我必须做的是:

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

现在,所有修改都在update语句中生成,不管是否真的有更改。这很有效。。。看起来有点老土

我遇到了这个问题,我看到的所有建议都不适用或不起作用

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

当更新属性时,我实际上调用了一个自定义的Set方法(因为还有其他一些东西需要更改以响应所讨论的主属性)

几个小时的挠头之后,我注意到我的Set方法是更新私有成员而不是公共属性,即这个


我所要做的就是把这个改成这个;一切都开始起作用了

> P>正确的答案是,许多人指出使用附加的超负荷,它接受布尔参数来考虑它被修改,(使用另一个过载的错误,它根本不起作用):< /P>
但是请注意,您可能仍然需要在“timestamp”类型的表中有一个“Version”列。

您的类中是否有导致干扰的部分方法,例如OnCreated()或OnChanged()?“你检查过你的模型了吗?”戴夫问。。。但你说的三联肠胃检查是什么意思?我的意思是现在还早,我还没有喝咖啡我的意思是,你有没有仔细检查过你的dbml文件的定义(数据类型、可空、关系)和你的db?明白了我现在正在这么做。。。到目前为止,一切看起来都很好。我的意思是,它确实改变了值,只是当我试图使它为零时,它不会改变!您能否验证您已经创建了SQL表的主键,并且linq对象知道这个小事实?Linq不会告诉你什么,只是不会更新表格。我希望这有帮助。你在@Gaspar Nagy上是对的。。。Linq到Sql忽略了更改。