Как поместить таблицу в кэш EntityFramework?

372
08 февраля 2017, 22:42

Программа рекурсивно обрабатывает директории и через COM читает специфические свойства определенных файлов. Новые свойства могут определяться пользователем, и быть доступными только у определенного файла. При чтении свойств мне нужно проверять есть ли уже в БД такое свойство и при его отсутствии добавлять, но как избежать запроса к БД для каждого сравнения?

Также не могу разобраться как после сохранения записи в Files и в Property добавить запись в FileProperties?

Заранее премного благодарен за уделенное время и внимание.

foreach(var path in paths){
  Files file;
  using(var context = new DbContext()){
    file = context.FirstOrDefault(f => ... );
  }
  if(file == null){
    file = new Files(){ ... };
    using(var context = new DbContext()){
      context.Files.Add(file);
      context.SaveChanges();
    }
    var specProps = GetSpecProps(path);
    using(var context = new DbContext()){
      foreach(var specProp in specProps){
        Property prop;
        // отправляет запрос на сервер, а как читать из "кеша"?
        prop = context.Property.FirstOrDefault( p => ...);
        if(prop == null){
          prop = new Property(){ ... };
          context.Property.Add(prop);
        }
        // как здесь добавить запись в FileProperties?
        // System.Data.Entity.Infrastructure.DbUpdateException: 
        // Не удалось обновить набор EntitySet "FileProperties", 
        // поскольку в нем имеется запрос DefiningQuery и 
        // отсутствует элемент <InsertFunction> в элементе 
        // <ModificationFunctionMapping> для поддержки текущей операции.
        // context.FileProperties.Add(new FileProperties() {
        //     File = file,
        //     Property = prop,
        //     property_value = specProp.Value.ToString()
        // };
      }
      context.SaveChanges();
    }
  }
}
Answer 1

Варианта тут два.

Вариант первый: вы загружаете таблицу на клиент целиком и помещаете в словарь для быстрого поиска по ней в памяти. Разумеется, это будет работать только если таблица маленькая:

var allProps = context.Properties.ToDictionary(p => p.property_name);

Только не надо в таком случае создавать по контексту БД на каждый файл, да еще и два раза. Вы можете в одном и том же контексте записать в БД сразу все файлы. За одну операцию сохранения.

Вариант второй. Надо ввести новую сущность, которая не будет иметь отображения в БД. Вместо этого, операция вставки будет отображена на хранимую процедуру, которая проверит существование свойства и создаст его при необходимости, после чего вернет ключ найденного или созданного свойства.

READ ALSO
Определить версии установленных DAO и ADO на c#

Определить версии установленных DAO и ADO на c#

Для одного старого приложения (VBA) нужно проверить среду, где устанавливается программаТ

293
Чтение из базы SqlReader C#

Чтение из базы SqlReader C#

Все работает, НО в password у меня получается значение "123 " значение в базе "123"

357
Текст из файла в строку

Текст из файла в строку

Программа должна считывать из текстового файла (txt) весь текст и записывать его в массив строк по 100 символов

379
Цифровая подпись интеркассы в asp.net [требует правки]

Цифровая подпись интеркассы в asp.net [требует правки]

Как сформировать цифровую подпись интеркассы в aspnet mvc

339