2015-12-31 3 views
9

Я работаю над проектом для подключения к базе данных PostgreSQL с использованием NpGsql EntityFramework 6. Я получаю заголовок исключения в вопросе, когда я пытаюсь выполнить запрос в GetAdminUsersCount:NpGsql EntityFramework 6 - «Операция уже выполняется»

public class GenieRepository : IDisposable 
{ 
    GenieDbContext db = new GenieDbContext(); 
    public IEnumerable<User> GetUsers() 
    { 
     return db.Users; 
    } 
} 

public int GetAdminUsersCount() 
{ 
    return repo.GetUsers().Where(u => u.Role.RoleName == "Administrator").Count(); 
} 

В чем причина этой ошибки и как ее решить?

+1

SideNote: ** PostGre Sql **: O, huh ??? Использовать [Postgres или PostgreSQL] (http://stackoverflow.com/tags/postgresql/info) –

+0

Какую версию NpgSql вы используете? Если вы устанавливаете на моно, какая версия? –

+0

NpgSql 3.0.4.0, Entity Framework 6.0 – teenup

ответ

7

мне удалось решить эту проблему с помощью ToList<T> сразу после запроса Linq, как это:

using (ElisContext db = new ElisContext()) { 
    var q = from a in db.aktie select a; 
    List<aktie> akties = q.ToList<aktie>(); 
    foreach (aktie a in akties) { 
     Console.WriteLine("aktie: id {0}, name {1}, market name {2}" 
       , a.id, a.name, a.marked.name); 
    } 
} 

Обратите внимание на q.ToList<T>, что делает трюк. .Net отложить выполнение инструкции linq до последнего момента, что может быть частью проблемы. Я попытался использовать q в foreach без успеха.

2

Проблема вызвана обратным типом метода GetUsers(). Поскольку он равен IEnumerable<User>, LINQ-to-SQL будет загружать результат в память (последовательно), а затем в памяти будут выполняться команды Where, OrderBy, Select, Count и т. Д. Когда оценивается условие Where, исходный результирующий набор все еще перебирается, но отношение User.Role должно быть разрешено в БД (откуда приходит сообщение об ошибке «Операция уже в прогрессе»).

Если возвращаемый тип изменяется на IQueryable<User>, запрос не будет выполняться до тех пор, метод Count не называется, и, кроме того, весь запрос будет переведен в SQL возвращаются только граф никогда не загрузки каких-либо User записи в память ,

Смотрите также это связано вопрос/ответ: Returning IEnumerable<T> vs. IQueryable<T>

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

Смежные вопросы