Entity Framework: с этой командой уже есть открытый DataReader - PullRequest
272 голосов
/ 01 февраля 2011

Я использую Entity Framework и иногда получаю эту ошибку.

EntityCommandExecutionException
{"There is already an open DataReader associated with this Command which must be closed first."}
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands...

Несмотря на то, что я не делаю никакого ручного управления соединением.

эта ошибка возникает периодически.

код, вызывающий ошибку (сокращен для удобства чтения):

        if (critera.FromDate > x) {
            t= _tEntitites.T.Where(predicate).ToList();
        }
        else {
            t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
        }

с использованием шаблона Dispose для открытия нового соединения каждый раз.

using (_tEntitites = new TEntities(GetEntityConnection())) {

    if (critera.FromDate > x) {
        t= _tEntitites.T.Where(predicate).ToList();
    }
    else {
        t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
    }

}

по-прежнему проблематично

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

Ответы [ 16 ]

1 голос
/ 30 января 2019

2 решения для смягчения этой проблемы:

  1. Принудительно кэшировать память, сохраняя ленивую загрузку с .ToList() после запроса, чтобы затем можно было выполнить итерацию по нему, открывая новый DataReader.
  2. .Include (/ дополнительные сущности, которые вы хотите загрузить в запросе /), это называется активной загрузкой, которая позволяет (действительно) включать связанные объекты (сущности) во время выполнения запроса с помощьюDataReader.
1 голос
/ 10 февраля 2016

Я обнаружил, что у меня была та же ошибка, и это произошло, когда я использовал Func<TEntity, bool> вместо Expression<Func<TEntity, bool>> для вашего predicate.

Как только я изменил все Func's на Expression's, исключение перестало генерироваться.

Я считаю, что EntityFramwork делает некоторые умные вещи с Expression's, которые он просто не делает с Func's

0 голосов
/ 05 апреля 2018

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

0 голосов
/ 15 июня 2017

Эту проблему можно решить, просто преобразовав данные в список

 var details = _webcontext.products.ToList();


            if (details != null)
            {
                Parallel.ForEach(details, x =>
                {
                    Products obj = new Products();
                    obj.slno = x.slno;
                    obj.ProductName = x.ProductName;
                    obj.Price = Convert.ToInt32(x.Price);
                    li.Add(obj);

                });
                return li;
            }
0 голосов
/ 16 февраля 2016

Если мы попытаемся сгруппировать часть наших условий в метод Func <> или расширение, мы получим эту ошибку, предположим, у нас есть код, подобный этому:

public static Func<PriceList, bool> IsCurrent()
{
  return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
              (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

Or

public static IEnumerable<PriceList> IsCurrent(this IEnumerable<PriceList> prices) { .... }

Это вызовет исключение, если мы попытаемся использовать его в Where (), вместо этого нам нужно создать предикат, подобный этому:

public static Expression<Func<PriceList, bool>> IsCurrent()
{
    return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
                (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

Более подробно можно прочитать по адресу: http://www.albahari.com/nutshell/predicatebuilder.aspx

0 голосов
/ 05 июня 2013

Я решил эту проблему, используя следующий раздел кода перед вторым запросом:

 ...first query
 while (_dbContext.Connection.State != System.Data.ConnectionState.Closed)
 {
     System.Threading.Thread.Sleep(500);
 }
 ...second query

Вы можете изменить время сна в миллисекундах

P.D. Полезно при использовании потоков

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