Вы должны помнить, что запросы IQueryable фактически не выполняются в хранилище данных, пока вы не перечислите их.
using (var dataContext = new dataContext())
{
Эта строка кода фактически не делает ничего, кроме сборки SQL-оператора
users = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false);
. Any () - операция, которая перечисляет IQueryable, поэтому SQL отправляется в источник данных (через dataContext), а затем выполняется против него действие .Any ()
if(users.Any() == false)
{
return null;
}
}
. Ваша строка «проблема» повторно использует построенный выше sql, а затем выполняет дополнительная операция (.Select ()), которая просто добавляет к запросу. Если вы оставили его здесь, никакое исключение, кроме вашей проблемной строки
return users.Select(x => x.ToInfo()).ToList(); // this line is the problem
, вызывает .ToList (), который перечисляет IQueryable, что приводит к отправке SQL-кода в источник данных с помощью используемого dataContext в исходном запросе LINQ. Поскольку этот dataContext был удален, он уже недействителен, и .ToList () выдает исключение.
Это «почему он не работает». Исправление состоит в том, чтобы переместить эту строку кода в область вашего объекта dataContext.
Как правильно использовать его - это еще один вопрос с несколькими, возможно, правильными ответами, которые зависят от вашего приложения (Forms vs. ASP.net vs MVC и т. Д.). Образцом, который это реализует, является шаблон Единицы работы. Для создания нового объекта контекста практически нет затрат, поэтому общее правило состоит в том, чтобы создать его, выполнить свою работу и затем избавиться от него. В веб-приложениях некоторые люди создадут контекст для каждого запроса.
Rico Mariani является парнем производительности в MSFT, и у него есть хороший ряд на LINQ к производительности sql:
Ничего не видели со сравнением перфекта с библиотеками, которые Вы упоминаете, но это должно дать Вам общее представление о базовом перфекте.
У нас был ужасный опыт работы с производительностью ADO.NET Entities с использованием LINQ: наследование сильно замедляет работу. Небольшая база данных (скажем, 100 записей или около того) с 20 классами, большинство из которых унаследованы, запрос может легко занять 10 секунд.
Поэтому сделайте дерево наследования как можно более мелким при использовании ADO.NET Entities + LINQ.
Вот именно то, что вы ищете, см. Тесты ORM на ormBattle.net