0

I have a DevExpress GridControl with rows from the database. The currently selected row is captured using a binding, and it's name is SelectedItem.

I then try to edit the data for that row like so:

var entry = context.Entry(SelectedItem);
if (entry != null)
{
    entry.Entity.Name = addForm.InstrumentName;
    entry.Entity.InstrumentType = addForm.InstrumentType;
    entry.Entity.Units = addForm.Units;
    entry.Entity.RollOver = addForm.RollOver;
    entry.State = EntityState.Modified;
    try { context.SaveChanges(); }
    catch (Exception ex)
    {
        //ex is of type DbUpdateConcurrencyException
    }
}

However, if I use FirstOrDefault to pull a fresh entity using just the SelectedItem.ID, then I can make changes and save the record.

Now, I've been laboring under the idea that the former method is the preferred one for making changes to an entity, especially when that entity reference is already at hand. Am I wrong? If so, why?

If I'm not, then can someone help to explain why I might get a concurrency error?

Exception Details:

DbUpdateConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.

Resulting Log Output (as requested):

UPDATE [dbo].[Instrument]
SET [EquipmentID] = @0, [Name] = @1, [InstrumentType] = @2, [Units] = @3, [RollOver] = @4
WHERE (([ID] = @5) AND [Timestamp] IS NULL)
SELECT [Timestamp]
FROM [dbo].[Instrument]
WHERE @@ROWCOUNT > 0 AND [ID] = @5
-- @0: '0' (Type = Int32)
-- @1: 'Hour meter' (Type = String, Size = 50)
-- @2: '0' (Type = Int32)
-- @3: 'hours1' (Type = String, Size = 25)
-- @4: '999999.00' (Type = Decimal, Precision = 18, Scale = 2)
-- @5: '2' (Type = Int32)
-- Executing at 4/26/2018 3:57:12 PM -04:00
-- Completed in 2 ms with result: SqlDataReader
DonBoitnott
  • 10,787
  • 6
  • 49
  • 68
  • What is the full error message you get and what is the `InnerException` error message, in case the property is set? – Progman Apr 23 '18 at 18:40
  • @Progman I've updated the question with exception details. – DonBoitnott Apr 26 '18 at 11:43
  • How do you know your `SelectedItem` object will be a new record or will update an existing record? – Progman Apr 26 '18 at 16:41
  • @Progman I don't follow. It's an entity representing a record from the database. It cannot be a new record, because it already is one. – DonBoitnott Apr 26 '18 at 16:43
  • 1
    Please add `context.Database.Log = it => System.Diagnostics.Debug.Write(it);` to your context to see the SQL statements generated by the Entity Framework. Edit your question to include the SQL statements generated. Based on https://stackoverflow.com/questions/1836173/entity-framework-store-update-insert-or-delete-statement-affected-an-unexpec/1836304#1836304 it looks like the values in the database has changed in the meantime and/or you have problems with your primary key. But according to https://msdn.microsoft.com/en-us/library/jj592676(v=vs.113).aspx it should work. – Progman Apr 26 '18 at 17:30
  • @Progman I see now that it's probably this: `[Timestamp] IS NULL`. But why would it be presuming `NULL` for that value? The `SelectedItem` entity does have `null` for that value. I wonder why it wasn't selected initially in the grid? – DonBoitnott Apr 26 '18 at 20:05
  • You have to edit your question to include the source codes of your classes, see https://stackoverflow.com/help/mcve. Otherwise we can't tell why this specific value couldn't be loaded or why the value gets dropped. Also use a debugger to see where the value becomes `NULL`. – Progman Apr 26 '18 at 20:09

0 Answers0