Ошибка «Уже существует открытый DataReader, связанный с этой командой, который необходимо закрыть в первую очередь» в запросе Entity Framework linq - PullRequest
1 голос
/ 13 июля 2020

Я регулярно (но не всегда) получаю эту ошибку

Уже существует открытый DataReader, связанный с этой командой, который должен быть сначала закрыт

при выполнении запроса показано в GetRecentClients. После того, как я просмотрел его, я обнаружил, что он должен что-то делать с одновременным открытием двух соединений и что включение MARS должно помочь, но я бы предпочел не делать этого.

Is есть ли другой способ обойти это, и откуда именно это второе соединение происходит? Нет никаких включений или чего-то подобного, встреча представляет собой довольно простую сущность только с базовыми свойствами типа c.

public static async Task<RecentClientsModel> GetRecentClients(int managerId, IUnitOfWork unitOfWork)
{
    var recentViews = (await unitOfWork.GetRepository<Meeting>().Get(
        source => source
            .Where(a => a.Type == StatusType.Viewed && a.ManagerId == managerId)                    
            .GroupBy(c => c.ClientId)
            .Select(gr => gr.OrderByDescending(g => g.Date).FirstOrDefault())
            .OrderByDescending(a => a.Date)
            .Take(10))).ToArray();
    
    //...
}

public class Meeting
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public StatusType Type { get; set; }
    public int? ClientId { get; set; }
    public int? ManagerId { get; set; }
}

public async Task<IEnumerable<T>> Get(Func<IQueryable<T>, IQueryable<T>> queryBuilder)
{
    return await queryBuilder(_context.Set<T>()).ToListAsync();
}

1 Ответ

0 голосов
/ 13 июля 2020

Нашел этот ответ: Entity Framework: уже существует открытый DataReader, связанный с этой командой

В котором говорится, что он, вероятно, сработал из-за вложенных запросов или ленивой загрузки. Похоже, что единственный способ исправить это - не использовать ленивую загрузку или включить MARS (несколько активных наборов результатов).

В вашем случае это, вероятно, не фактическое второе соединение, а другой набор результатов, поступающий из такое же соединение. Мне также интересно, могло ли это быть из-за ToListAsync().

На самом деле, теперь, когда я снова смотрю на это, это может быть что-то с вызовом gr.OrderByDescending() в середине запроса? Это может быть попытка перечислить набор результатов в середине внешнего набора результатов. Может быть, попробуйте переписать запрос (даже неправильно), чтобы избежать чего-то подобного, и посмотрите, исчезнет ли проблема.

...