У меня есть приложение. 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? Есть ли другое решение этой проблемы?