I am getting the DbUpdateConcurrencyException
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException : The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See https://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
when I have a SQLServer database, and no other programs accessing the same,
and no async in node.
The self contained NUnit function is
1. Delete existing records with the given name by
a. Fetch the records using DbSet.Where with the given name
b. Execute DbSet.RemoveRange
c. Execute DbContext.SaveChanges
2. Create a Database record
a. Execute DbSet.Add
b. Execute DbContext.SaveChanges
3. Refresh the record
a. Fetch the records using DbSet.Where with the primary keys
(This fetches same record as written, but in a separate C# variable)
b. Make the modifications on the C# structure
c. Execute DbContext.SaveChanges
The C# function (simple one)
DbUserView initialView = new DbUserView {
userName = 'test', fromUrl = 'http://localhost:5000',
eventType = 'quiz', sectionId = 'firstSection', pageId = 'firstPage',
startTime = DateTime.Now, lastActiveTime = DateTime.Now };
[Test]
public void Expt2() {
string? userName = initialView.userName;
var dbUserViews = exptContext.userViews.Where(
dbUserView => dbUserView.userName == userName);
if (dbUserViews.Count() > 0) {
exptContext.userViews.RemoveRange(dbUserViews);
exptContext.SaveChanges();
}
Thread.Sleep(2000);
exptContext.userViews.Add(initialView);
exptContext.SaveChanges();
Thread.Sleep(2000);
DbUserView? _refreshView = exptContext.userViews.Find(
initialView.userName, initialView.fromUrl, initialView.startTime);
if (_refreshView == null)
Assert.Fail("Db fetch gave null view");
else {
DbUserView refreshView = (DbUserView)_refreshView;
refreshView.lastActiveTime = DateTime.Now.ToUniversalTime();
exptContext.userViews.Update(refreshView);
exptContext.ChangeTracker.DetectChanges();
var change = exptContext.ChangeTracker.DebugView.LongView;
exptContext.SaveChanges();
}
}
The database record (nothing fancy)
[Table("user_views")]
[PrimaryKey(nameof(userName), nameof(fromUrl), nameof(startTime))]
public class DbUserView {
[Column("user_name")]
public string userName { get; set; }
[Column("from_url")]
public string fromUrl { get; set;}
[Column("event_type")]
public string eventType { get; set;}
[Column("frame_id")]
public string frameId { get; set;}
[Column("sub_frame_id")]
public string subFrameId { get; set;}
[Column("start_time")]
public DateTime startTime { get; set; }
[Column("last_active_time")]
public DateTime lastActiveTime { get; set; }
}
and the context is (nothing fancy)
public class ExptContext : DbContext {
public DbSet<DbUserView> userViews { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string? connStr = Environment.GetEnvironmentVariable("SQLCONNSTR_DbConn");
optionsBuilder.UseSqlServer(connStr);
}
public static ExptContext dbContext = new ExptContext();
}
I also tried to print the changes using code below, but debug log was straightforward (since I have only one record)
private void showChanges() {
exptContext.ChangeTracker.DetectChanges();
var changes = exptContext.ChangeTracker.DebugView.LongView.ToString();
Console.WriteLine(changes);
}
Parts of the code work sometimes, and it is pretty random.
Specific questions (in addition to your thoughts)
- Is there something basic I am missing?
- Is there a way to debug log DbContext.SaveChanges?
- How does SaveChanges run? Can network timeouts cause this error?