Need a centralized solution to get the resulting Entity
as persisted to the Db, potentially inside the SaveChangesAsync()
and SaveChanges()
methods of my DbContext
or via an event listener.
Need resulting entity value to contain all new .ValueGeneratedOnAdd[Updated/etc]()
properties. i.e.RowVersion
, Updated
, etc..
The purpose is to communicate the before and after of the Entity
for concurrency communication.
This is what I have thus far: This first method incurrs an extra, unnecessary Db hit.
public override async Task<int> SaveChangesAsync(
CancellationToken cancellationToken = new CancellationToken() )
{
var before = ChangeTracker.Entries().AsEnumerable().First();
var res = await base.SaveChangesAsync(cancellationToken);
/* ********************************************************
I can do the following, but this results in an extra
DbQuery. I know that if this were a consumer
method with entity, after I called SaveChangesAsync() it
would have the new resulting values. Just not sure how
to access here inside SaveChangesAsync()?
********************************************************** */
await ChangeTracker.Entries().AsEnumerable().First().ReloadAsync();
/* ********************************************************
^ Additionally, ReloadAsync has a "Note, however, that an
Added entity may not yet have had its permanent key value
created.
********************************************************** */
var after = ChangeTracker.Entries().AsEnumerable().First();
return res;
}
Additionally I have subscribed to the new state change events Tracked
and StateChagned
that are mentioned or linked on github issue EntityFrameworkCore - Lifecycle hooks #626:
For Ex:
public class StateListener : IEntityStateListener
{
public void StateChanging(InternalEntityEntry entry, EntityState newState)
{
Console.WriteLine(
" Changing {0} from {1} to {2}.",
entry.Entity.GetType().Name, entry.EntityState, newState);
}
public void StateChanged(InternalEntityEntry entry,
EntityState oldState, bool fromQuery)
{
Console.WriteLine(
" Changed {0} to {1} from {2}.",
entry.Entity.GetType().Name, entry.EntityState, oldState);
}
public void StateChanged(InternalEntityEntry entry, EntityState oldState,
bool skipInitialFixup, bool fromQuery)
{
Console.WriteLine(
" Changed {0} from {1} to {2}.",
entry.Entity.GetType().Name, oldState, entry.EntityState);
}
}
However the newState
and the InternalEntityEntry
in StateChanged
all posess the values that should save and not the new values that are set by the Db, such RowVersion
, Changed
etc..