简体   繁体   English

Linq-to-Sql SubmitChanges没有更新字段......为什么?

[英]Linq-to-Sql SubmitChanges not updating fields … why?

I posted this question yesterday evening, which has led me to discover a huge problem! 我昨天晚上发布了这个问题 ,这让我发现了一个很大的问题!

I have a decimal column in my database called Units, anytime I set the value of the column to a NON ZERO, and SubmitChanges the column updates with the new value. 我的数据库中有一个名为Units的十进制列,只要我将列的值设置为NON ZERO,并使用新值SubmitChanges列更新。 If I try to set the value of the column to ZERO, the SubmitChanges does not update the column. 如果我尝试将列的值设置为ZERO,则SubmitChanges不会更新列。

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

I've taken a look at the DataContext log and I can see that the field with the ZERO value is not included in the query. 我查看了DataContext日志,我可以看到查询中不包含具有ZERO值的字段。 Even if I try to hard code the change Linq ignores it. 即使我试图对代码进行硬编码,Linq也会忽略它。

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

Needless to say this is killing me! 不用说这是杀了我! Any ideas why this happening? 任何想法为什么会这样?

Solution

I figured out my problem with the help of the SO community. 我在SO社区的帮助下想出了我的问题。 My problem was being caused by the fact when I created my entity to attach, the default value of the column was set to zero, so when it tried to assign the value to zero ... LinqToSql says hey ... nothing changed, so I am not updating the value. 我的问题是由于我创建我的实体附加时的事实,列的默认值设置为零,所以当它试图将值分配给零时... LinqToSql说嘿......没有改变,所以我没有更新价值。

What I am doing now ... just to make it work is the following: 我现在在做什么......只是为了让它发挥作用如下:

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

That seems to force all the values to write themselves to the database. 这似乎迫使所有值将自己写入数据库。 This works for now. 这适用于现在。

I have tried to reproduce this with a the following code, but for me it works. 我试图用下面的代码重现这个,但对我来说它是有效的。

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

So I think there must be something special in your domain that causes this. 所以我认为你的领域必须有一些特殊的东西导致这一点。 I suggest you to create a such simple repro with your domain model and see what happens. 我建议你用你的域模型创建一个这样简单的repro,看看会发生什么。

LINQ to SQL ignores updates to the current value, so if the field was already zero, you may not see any updates. LINQ to SQL忽略对当前值的更新,因此如果该字段已经为零,则可能看不到任何更新。

Off: The OR/M you use is LINQ to SQL . 关:您使用的OR / M是LINQ to SQL LINQ is the name of the querying capability in .NET, but LINQ does not define nor implement any update logic. LINQ是.NET中查询功能的名称,但LINQ不定义也不实现任何更新逻辑。 So the issue relates to LINQ to SQL, not LINQ. 所以问题与LINQ to SQL有关,而不是LINQ。

Obvious question, but are you sure the column is mapped in the dbml / mapping file? 明显的问题,但你确定列是在dbml / mapping文件中映射的吗?

Also - is it a calculated column? 另外 - 它是一个计算列? (ie price => units * unitprice) (即价格=>单位* unitprice)

I figured out my problem with the help of the SO community. 我在SO社区的帮助下想出了我的问题。 My problem was being caused by the fact when I created my entity to attach, the default value of the column was set to zero, so when it tried to assign the value to zero ... LinqToSql says hey ... nothing changed, so I am not updating the value. 我的问题是由于我创建我的实体附加时的事实,列的默认值设置为零,所以当它试图将值分配给零时... LinqToSql说嘿......没有改变,所以我没有更新价值。

What I am doing now ... just to make it work is the following: 我现在在做什么......只是为了让它发挥作用如下:

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

That seems to force all the values to write themselves to the database. 这似乎迫使所有值将自己写入数据库。 This works for now. 这适用于现在。

Some more information ... I figured out my problem ... it's more of a lack of understanding about LinqToSql ... where I am doing: 更多信息......我想出了我的问题...更多的是对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
           }
     }
}

I thought this would load the original values ... what happens is that it creates a new object with default values ... empty values, like 0 for decimals, Guid.Empty for uniqueidentifiers and so on. 我认为这会加载原始值...会发生的是它创建一个具有默认值的新对象...空值,如小数为0,uniqueidentifiers为Guid.Empty等等。

So when it updates the properties it sees the Units already as 0 and it sets it to zero. 因此,当它更新属性时,它会将Units视为0,并将其设置为零。 Well LinqToSql doesn't recognize this as a change so it doesn't up date the field. 好吧LinqToSql不会将此识别为更改,因此它不会更新该字段。 So what I have had to do is the following: 所以我必须做的是以下内容:

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

Now all the modifications are generated in the update statement whether there is really a change or not. 现在,无论是否真的发生了更改,都会在update语句中生成所有修改。 This works ... seems a bit hackish! 这工作......似乎有点hackish!

The correct answer is as many pointed out to use the special overload of Attach which accepts a boolean parameter to consider it as modified, (make the mistake of using another overload and it simply won't work): 正确的答案是许多人指出使用Attach的特殊重载,它接受一个布尔参数来将其视为已修改,(使用另一个重载的错误,它根本不起作用):

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

Note however that you still might need to have a "Version" column in the table of type "timestamp". 但请注意,您仍可能需要在“timestamp”类型的表中包含“Version”列。

I had this problem and all the suggestions I'd seen didn't apply or work. 我有这个问题,我看到的所有建议都没有适用或工作。

But I found I had made a very simple mistake! 但我发现我犯了一个非常简单的错误!

When updating the property I was actually calling a custom Set method (because there were other things that needed to be changed in response to the main property in question). 更新属性时,我实际上调用了一个自定义Set方法(因为还有其他一些东西需要更改以响应相关的主要属性)。

After hours of head scratching I noticed that my Set method was updating the private member not the public property, ie this._Walking = value; 经过数小时的头部刮擦,我注意到我的Set方法正在更新私有成员而不是公共属性,即this._Walking = value;

All I had to do was change this to this.Walking = value; 我所要做的就是将其改为this.Walking = value; and it all started to work! 一切都开始奏效了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM