We faced a real tough issue the other day, where we really had to take some time to see what was going on behind the scenes of Entity Framework.
We love creating applications with C# and leverage Entity Framework but this time EF wasn’t as nice to us as it usually is. Here is what happened:
While using the repository layer approach, we were saving and updating our records by using uow.SaveChanges();
, a fairly common approach. To prevent concurrencies from happening, we implemented a concurrency check similar to the following:
if (entityRecord.LastModifiedDateTime != cachedRecord.LastModifiedDateTime) { RepositoryCache.Remove(cachedRecord.Id.ToString(), typeof(T).Name); throw new DbUpdateConcurrencyException(); }
This failed in instances where we were sure it shouldn’t fail, e.g. when we updated a record twice in a row. We found that the issue was due to us using DateTime
as the column of choice for all our DateTime fields. Entity Framework however uses DateTime2
with a higher precision that DateTime
. So the cached record was apparently more precise than the one stored in the database, causing the simple if-statement to trigger.
Our solution was simple – let’s modify all existing database columns of type DateTime to the more precise (and recommended for new development) DateTime2. Here is our fix which we used in our DbContext:
modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
And that’s it. Run a migration and you should be all set. To be fair, this was not Entity Frameworks fault, it was our mistake. We should have had been using DateTime2
all along! Watch out for this, when starting your next project (note to myself!).
0 Comments