Вместо непосредственного чтения таблиц поиска в базе данных команда хочет применить (a) MemoryCache или (b) Entity Framework InMemoryDatabase / SQLite для уменьшения использования базы данных и увеличения производительности памяти.
Как автоматически переслать существующие таблицы поиска DbContext Linq-запросы для чтения из памяти? Таблицы поиска меняются только несколько раз в год, в основном они статические, AddressCategory, CustomerStatus, ProductType. База данных состоит из таблиц больших транзакций, которые должны быть считаны из базы данных, и таблиц поиска, которые должны быть считаны из памяти.
Примечание. Компания имеет существующие запросы Linq и хочет автоматически переслать существующий код в кэш.
Метод 1: предлагаемое решение EF InMemory / SQLite:
Копирование / вставка оригинального DbContext (StoreContext) в новую копию DbContext, называемую StoryMemoryContext. В Startup.cs
services.AddDbContext<StoreContext>(options => options.UseSqlServer(@"Server=localhost;Database=StoreDatabase";));
services.AddDbContext<StoreMemoryContext>(options => options.UseInMemoryDatabase(databaseName: "StoreMemoryContext"));
services.AddDbContext<CustomDbContext>(options => options.UseSqlServer(@"Server=localhost;Database=StoreDatabase")));
Сохранить миниатюрные таблицы поиска Lookup в InMemoryDatabase 'StoryMemoryContext' (около 5 Мб максимум).
- Имейте CustomDbContext наследовать от оригинала, где Original StoreContext пересылает методы доступа к StoryMemoryContext.
Циклический код всех таблиц поиска с T4 или Powershell Automation
public class CustomDBContext : StoreContext
{
public StoreMemoryContext _storeMemoryContext; = new StoreMemoryContext();
public CustomDBContext()
{
}
public override DbSet<ProductType> ProductType
{
set
{
base.ProductType = value;
_storeMemoryContext.ProductType = value;
}
get
{
return _storeMemoryContext.ProductType;
}
}
Вопросы:
1) Будет ли работать этот метод Get? Есть вопросы для исследования? Не стесняйтесь пересматривать / редактировать в ответе. Открытое для любого решения не только это,
Get-аксессоры, кажется, работают.
При выполнении _customDbContext.ProductType.ToList()
он читает InMemory EF.
_customDbContext.CustomerTransaction.Include(c => c.ProductType).ToListAsync()
прочитает базу данных, соответствующую предполагаемому поведению. Не нужно читать транзакции клиентов из больших таблиц без просмотра из базы данных InMemory.
2) Установка Accessors работает только частично, так как существует множество способов изменить DBSet и DBContext: Add, AddRange, Удалить, Добавить Entity Graph (сложно отследить) Физические справочные таблицы меняются только пару раз в год. Мысль об ChangeTracker, однако для размещения оператора If после каждого SaveChanges()
для проверки, изменилась ли таблица поиска / затем обновить базу данных InMemory, это может замедлить работу приложения, поскольку у нас 500 транзакций в секунду. (это то, что мне сказали - желая услышать больше мнений о ChangeTracker и влиянии на производительность / скорость) Примечание. Физические таблицы и таблицы поиска InMemory могут иметь 30-минутный период синхронизации между двумя в соответствии с требованиями клиента, поскольку таблицы поиска редко изменяются. Однако почти мгновенная синхронизация данных между двумя является целевым решением для вопроса (<5 секунд). </p>
Метод 2: MemoryCache не работает: Похоже, создайте Inherited / custom DbContext, где чтение переопределяет впередтаблицы поиска в MemoryCache. Хранение DBContext в MemoryCache хранит только IQueryable, а не фактические материализованные значения. Переход от контроллера к контроллеру обновляет DbContext и очищает кеш, не стесняйтесь пересматривать / редактировать в ответе.
public class CustomDBContext : EcommerceContext
{
public CustomDBContext(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public override DbSet<ProductType> ProductType
{
get
{
return _memoryCache.Get<DbSet<ProductType>>("ProductTypeMemoryCache");
}
}
Обновление:
Ответ от Дэвида Брауна не будет работать в соответствии с требованиями вопроса, как и использование типа
var pt2 = db.Cache.LK_ProductTypes; //from cache
Компания имеет многосуществующие запросы, и хотите переслать существующий код в кэш. Кроме того, программисты могут забыть применить Cache, поэтому приведенный ниже код должен автоматически пересылать
var pt1 = db.LK_ProductTypes.ToList() ;
У нас есть смесь больших транзакционных таблиц, которые не должны кэшироваться, и небольших таблиц поиска.
Администратор базы данных непозволяют использовать таблицы, оптимизированные для памяти SQL Server, из-за некоторых ограничений. Память Оптимизированные ограничения
Ресурсы:
Нужно ли DbContext MemoryCache или Redis в Net Core?
Каксделать контекст данных Entity Framework доступным только для чтения
Net Core: автоматически обновлять кэш таблицы поиска после сохранения Entity Framework и UnitOfWorkPattern
Использование EF Core 2.2,