添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams
Case newCase = new Case(...);
dbContext.Entry(newCase).State = EntityState.Modified;
dbContext.SaveChanges();

When updating I have this message:

Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded

There is no concurrency, since I am using the db on my machine.

If I go to SQL profiler to see the query that is executed, the condition is:

WHERE [Id] = @p0 AND [RowVersion] = @p14;

in this condition, @p0 is 1 and @p14 is NULL, exactly like the record that I want to modify. however, if I manually launch this query in SQL Server after removing the RowVersion part of the query, it succeeds, updating 1 row.

What can be the problem and how can I solve it?

EDIT:

I tried to select the record just before updating it, but the error is the same:

    IEnumerable<Case> cases = from c in dbContext.Cases where c.Id.ToString() == "1" select c;
    Case cs = cases.SingleOrDefault();
    dbContext.Entry(cs).State = EntityState.Modified;
    dbContext.SaveChanges();

Here is the complete error:

An exception of type 'Microsoft.Data.Entity.DbUpdateConcurrencyException' occurred in EntityFramework.Core.dll but was not handled in user code

Additional information: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.

And here is the query from Sql Profiler:

exec sp_executesql N'SET NOCOUNT OFF;
UPDATE [Case]
        [Closed] = @p1
      , [Comment] = @p2
      , [ContactComment] = @p3
      , [ContactId] = @p4
      , [CreatedBy] = @p5
      , [CreatedDateTime] = @p6
      , [Description] = @p7
      , [Email] = @p8
      , [LastModifiedBy] = @p9
      , [LastModifiedDateTime] = @p10
      , [OpenedDateTime] = @p11
      , [Phone] = @p12
      , [RowVersion] = @p13
      , [SlaConsumedTime] = @p15
      , [SlaSuspended] = @p16
      , [SlaTotalTime] = @p17
      , [Status] = @p18
      , [Title] = @p19
WHERE 
    [Id] = @p0
    AND [RowVersion] = @p14;
SELECT @@ROWCOUNT;',
N'@p0 int,@p1 bit,@p2 nvarchar(max) ,@p3 nvarchar(max) ,@p4 int,@p5 int,@p6 datetime2(7),
@p7 nvarchar(4000),@p8 nvarchar(4000),@p9 int,@p10 datetime2(7),@p11 datetime2(7),
@p12 nvarchar(max) ,@p13 varbinary(max) ,@p14 varbinary(max) ,@p15 time(7),@p16 bit,
@p17 time(7),@p18 int,@p19 nvarchar(4000)',
@p0=1,@p1=0,@p2=NULL,@p3=NULL,@p4=0,@p5=1,@p6='2015-09-23 09:07:55.7041023',@p7=N'y',
@p8=N't@f.f',@p9=1,@p10='2015-09-23 09:50:02.9934006',@p11='2015-09-23 09:07:55.6796028',
@p12=NULL,@p13=NULL,@p14=NULL,@p15='00:00:00',@p16=0,@p17='00:00:00',
@p18=0,@p19=N'y'
                your Case entity surely has a RowVersion property, this is used for  concurrency check. But when you create a Case with new, that property does not have the original value currently stored in database. So the WHERE condition failed, you have to manually set the original values for RowVersion with some value fetched from database before calling SaveChanges().
– Hopeless
                Sep 23, 2015 at 9:23
                if so the query failed reasonably (I was wrong when said the query should have succeeded) - because RowVersion = NULL will never be true, it should be RowVersion is NULL). But the query is auto-generated so we cannot easily make it be translated to Is NULL instead of = NULL. However I think you configure the model wrong, the RowVersion should not be nullable. Also somehow you should ensure it to be auto-generated whenever a new record is added/modified. I would use IsRowVersion() method to configure it.
– Hopeless
                Sep 23, 2015 at 10:44
                In fact I thought it would auto-generate the values of RowVersion. I tried doing RowVersion = new byte[] { 0x20 } when creating a new record, and after this the update worked. But I will try to understand this RowVersion Logic (if I don't add the column, Code First does not create the table). Thank you for your help.
– Sean
                Sep 23, 2015 at 10:56
Case newCase = new Case(...);
dbContext.Entry(newCase).State = EntityState.Modified;
dbContext.SaveChanges();

Check your object, does it pass Primary Key Null. This Exception is Generally due this reason only.

That was it! Passing a null value is fine, as long as you configure autoincrement on your DB. – lenny Aug 17, 2021 at 11:56 `Key1` INT(11) NOT NULL, `Value` LONGBLOB NULL DEFAULT NULL, `Key2` INT(11) NOT NULL DEFAULT -1, PRIMARY KEY (`Key1`, `Key2`)

When I try to insert new row with Key2 = 0 it fails with same error.

DbUpdateConcurrencyException: 'Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.

My solution is to avoid saving 0 as key value. It seems to be treated as NULL and cannot be part of valid primary key. Hope this will save someone's time.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.