Заставить DbContext перезагрузить все данные из кэша? - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть приложение. net core 3.1, которое использует EF core для персистентности. В моей модели сущности у меня есть несколько базовых типов и несколько конкретных типов, которые получены из этих базовых типов с использованием модели таблицы на иерархию.

В некоторых конкретных c случаях мне нужно изменить реальный тип записи путем изменения значения столбца дискриминатора. Я не могу заново создать новую сущность и скопировать свойства (частично из-за внешних ключей, указывающих на эту сущность).

Я написал простой метод, который выполняет эту операцию, используя Database.ExecuteSqlInterpolated(). Это работает очень хорошо, но в моих тестах, чтобы правильно перезагрузить строку, мне нужно заново создать DbContext (в противном случае старый экземпляр все еще находится в кэше).

В моем В тестовом примере я мог бы легко воссоздать этот DbContext, но в коде ASP. net (в основном контроллеры) это намного сложнее, потому что контекст вводится DI в конструктор класса.

Вот код из моего тестового примера (немного упрощенный, удалив параметры инициализации сущности для обязательных столбцов, не связанных с проблемой):

[Fact]
public async Task ChangeAccountNatureTest()
{
    // Add a test account instance of type GeneralLedgerAccount
    AccountBase account = new GeneralLedgerAccount(); // this will set discriminator field AccountType to AccountType.GeneralLedger
    Db.Add(account);
    await Db.SaveChangesAsync();
    Guid accountID = account.ID;
    using var NewDB = fixture.DbContextFactory()();
    await NewDB.Database.BeginTransactionAsync();
    try
    {
        NewDB.Database.ExecuteSqlInterpolated($"UPDATE [Accounts] SET [AccountType]={(int)AccountType.Bank} where [ID]={accountID}");
        NewDB.Database.CommitTransaction();
    }
    catch
    {
        NewDB.Database.RollbackTransaction();
        throw;
    }
    // Reload the account and verify that the type has been changed
    ResetDBContext(); // this is implemented in thebase class. It uses the AppDbContext factory to recreate the Db instance
    account = await Db.Set<AccountBase>().FindAsync(accountID);
    Assert.Equal(AccountType.Bank, account.AccountType); // can't use typeof because it's actually a lazy-loading proxy
}

Итак, мой вопрос:

Есть ли способ сообщить DbContext, что указанная c сущность должна быть удалена из кэша ? Или что он должен полностью очистить кэш для экземпляра DbContext? Есть ли другое решение этой проблемы?

...