Linq-to-Sql SubmitChanges does not update fields ... why?

Yesterday I posted this question , which made me detect a huge problem!

I have a decimal column in my database called Units when I set the column value to NON ZERO and SubmitChanges updates the columns with the new value. If I try to set the column value to ZERO, SubmitChanges does not update the column.

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

I looked at the DataContext log and I see that a field with a null value is not included in the request. Even if I try to discredit the change, Linq ignores it.

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

Needless to say, this is killing me! Any ideas why this is happening?

Decision

I figured out my problem using the SO community. My problem was caused by the fact that when I created the object to join, the default value for the column was set to zero, so when he tried to set the value to zero ... LinqToSql says hey ... nothing changed, so I didn’t updating the value.

What I'm doing now ... just to make it work is the following:

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

It seems that all values ​​are written to the database. It works for now.

+6
c # linq linq-to-sql
source share
6 answers

I figured out my problem using the SO community. My problem was caused by the fact that when I created the object to join, the default value for the column was set to zero, so when he tried to set the value to zero ... LinqToSql says hey ... nothing changed, so I didn’t updating the value.

What I'm doing now ... just to make it work is the following:

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

It is like forcing all values ​​to write themselves to the database. It works for now.

+2
source share

I tried to reproduce this with the following code, but it works for me.

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

So, I think there should be something special in your domain that causes this. I suggest you create such a simple option with your domain model and see what happens.

LINQ to SQL ignores updates to the current value, so if the field is already zero, you may not see any updates.

Off: The OR / M you are using is LINQ to SQL. LINQ is the name of the query feature in .NET, but LINQ does not define or execute any update logic. Therefore, the problem is with LINQ to SQL, not LINQ.

+3
source share

The obvious question, but are you sure the column is displayed in the dbml / mapping file?

Also is this a calculated column? (i.e. price => units * unit of price)

+2
source share

More info ... I figured out my problem ... this is more due to a lack of understanding of LinqToSql ... where I do:

 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 decimal places, Guid.Empty for unique identifiers, etc. .

Therefore, when it updates the properties, it sees Units already as 0 and sets it to zero. Well, LinqToSql does not recognize this as a change, so it does not update the field. So I needed to do the following:

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

Now all the changes are generated in the update instruction, is there really a change or not. It works ... it seems a bit hacky!

+2
source share

The correct answer is that many have pointed to the use of a special Attach overload, which takes a logical parameter to consider it modified (make an error when using another overload and just don't work):

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

Please note that you may still need the “Version” column in the “timestamp” type table.

+1
source share

I had this problem and all the suggestions that I saw were not applied or did not work.

But I found that I made a very simple mistake!

When updating the property, I actually called the custom Set method (because there were other things that needed to be changed in response to the main property in question).

After frequent head crashes, I noticed that my Set method updated the private member, not the public property, that is this._Walking = value;

All I had to do was change this to this. Walking = value; and it all started to work!

0
source share

All Articles