Как получить все сохраненные значения сущностей в 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 но заброшенный из-за его природы.

Другие вопросы по тегам