Reputation: 145
I'm getting the following error when calling the db context SaveChanges method. The error suggests that it is due to a concurrency issue.
ERROR MESSAGE: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.Entity.Core.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
I've found several threads pertaining to this error, but no solutions that work in my case.
I believe the real problem has something to do with the entities ID field (ResourceAccessLogID) getting set to 0 by default. The ResourceAccessLogID field is an identity field that gets initialized by the database server. I'm not sure what I'm missing, or doing wrong.
NOTE: I've also tried creating a "fresh" context right before adding/inserting the new entity, and SaveChanges thinking something under the hood might be causing EF to think there is a concurency issue. But, this didn't help either.
Thanks in advance for anyone who can shed some light on this problem.
public class ResourceAccessLog
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ResourceAccessLogID { get; set; }
[Key]
[Column(Order = 1)]
public DateTime DateTime { get; set; }
[Required]
public long ResourceID { get; set; }
[Required]
[StringLength(128)]
public string UserID { get; set; }
public virtual Resource Resource { get; set; }
public virtual ApplicationUser User { get; set; }
}
private void SaveResourceAccessLog(string userID, long resourceID)
{
ResourceAccessLog resourceAccessLog = new ResourceAccessLog();
// resourceAccessLog.ResourceAccessLogID = 0; Default
resourceAccessLog.DateTime = DateTime.Now;
resourceAccessLog.ResourceID = resourceID;
resourceAccessLog.UserID = userID;
DbContext.ResourceAccessLogs.Add(resourceAccessLog);
DbContext.SaveChanges();
}
Upvotes: 0
Views: 527
Reputation: 143
It seems there is some issue with your logic, are you using mutithreaded environment and your DbContext is shared between them? If you are sure and intended to pass this feature called optimistic concurrency, you can try refreshing object context.
try
{
DbContext.SaveChanges();
}
catch (System.Data.Entity.Core.OptimisticConcurrencyException)
{
((System.Data.Entity.Infrastructure.IObjectContextAdapter)DbContext)
.ObjectContext.Refresh(System.Data.Entity.Core.Objects.RefreshMode.ClientWins, resourceAccessLog);
}
Upvotes: 1