Использование оператора using для Entity Framework DbContext в цикле foreach - PullRequest
1 голос
/ 18 февраля 2020

Есть анализатор, который анализирует текстовый файл, который содержит определение объекта. Определения объектов в текстовом файле имеют ключ-указатель заполнителя. Дескриптор заполнителя необходимо заменить на фактическое значение путем поиска значения дескриптора в БД. В моем приложении я использую ядро ​​Entity Framework для работы с БД.

Анализатор возвращает один объект за раз, и я ищу дескриптор и другие свойства в БД по одному за раз , Вот как выглядит код:

    IEnumerable<ObjectInfo> GetNextContent();

    IEnumerable<ObjectInfo> GetNextObjectInfo()
    {

        foreach (var item in parser.GetNextContent())
        {
            using (var dbContext = new ContentDbContext())
            {
                string key = item.Key;

                string id = dbContext.Contents.Find(key).ObjectId;
                item.Id = id;
                // Assign other fields...

                yield return item;
            }
        }
    }

Вопрос, который у меня возник, состоит в том, что в приведенном выше коде блок 'using' находится внутри foreach l oop. Это правильно делать? Другая мысль состоит в том, что я могу взять блок «using» за пределами foreach-l oop, но тогда я не уверен, как это отразится на итераторе в коде.

1 Ответ

3 голосов
/ 18 февраля 2020

Вы должны переместить ContentDbContext наружу для повышения производительности.

Это просто потому, что вам нужен только один context на запрос.

Один DbContext на веб-запрос. .. почему?

using (var dbContext = new ContentDbContext())
 {
    foreach (var item in parser.GetNextContent())
     {
            string key = item.Key;

            string id = dbContext.Contents.Find(key).ObjectId;
            item.Id = id;
            // Assign other fields...

            yield return item;
        }
    }

Обновлено

Вы также можете присоединиться, а затем убедиться, что все данные извлекаются одновременно

// You need to fetch all `item.Key` from `parser.GetNextContent()` to get all data in `dbContext.Contents`
var keys = parser.GetNextContent().Select(p => p.Key).ToArray();

var result = (from content in dbContext.Contents 
              join key in keys on content.Id equals key 
              select new 
{
  Id = content.ObjectId,
  //....
}  

Если вы используете C# 8, оператор использования может выглядеть следующим образом:

 using var dbContext = new ContentDbContext();

 foreach (var item in parser.GetNextContent())
 {
        string key = item.Key;

        string id = dbContext.Contents.Find(key).ObjectId;
        item.Id = id;
        // Assign other fields...

        yield return item;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...