Как получить все сохраненные значения сущностей в DbContext с помощью событий или переопределить SaveChangesAsync()
Нужно централизованное решение, чтобы получить результат Entity
как сохраняется в БД, потенциально внутри SaveChangesAsync()
а также SaveChanges()
методы моего DbContext
или через прослушиватель событий.
Нужно, чтобы полученное значение сущности содержало все новые .ValueGeneratedOnAdd[Updated/etc]()
свойства. т.е. RowVersion
, Updated
, так далее..
Цель состоит в том, чтобы сообщить до и после Entity
для параллельного общения.
Это то, что я имею до сих пор: этот первый метод вызывает дополнительный, ненужный удар Db.
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;
}
Кроме того, я подписался на новые события изменения состояния Tracked
а также StateChagned
которые упоминаются или связаны в выпуске github EntityFrameworkCore - ловушки жизненного цикла # 626: для примера:
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);
}
}
Тем не менее newState
и InternalEntityEntry
в StateChanged
все обладают значениями, которые следует сохранить, а не новыми значениями, установленными БД, такими как RowVersion
, Changed
так далее..
1 ответ
Ответ для тех, у кого похожий поиск. Задав этот вопрос, у меня возникло фундаментальное недоразумение. Я полагал, что сущность, сохраненная к БД, обновит все свои значения на SaveChanges[Async]()
, Я верил этому, потому что это поведение первичных ключей, описанное в разделе " Как я могу получить идентификатор вставленной сущности в платформе сущностей?"
Это не относится к свойствам, которые .ValueGeneratedOnAdd[Updated/etc]()
и не являются RowVersion или PrimaryKeys.
При таком понимании любое возможное решение предположительно потребует запроса к БД. Я подумал добавить такой запрос в OnCommandExecuting
а затем работает с результатом в OnCommandExecuted
но заброшенный из-за его природы.