3

Я заметил, что в зависимости от того, как я извлекаю данные из моей модели Entity Framework, я получаю разные типы результатов. Например, при получении списка сотрудников в конкретном отделе:Entity Framework - запрос из ObjectContext vs Querying from Navigation Property

Если я тяну непосредственно из ObjectContext, я получаю IQueryable<Employee>, которая на самом деле System.Data.Objects.ObjectQuery<Employee>:

var employees = MyObjectContext.Employees.Where(e => e.DepartmentId == MyDepartment.Id && e.SomeCondtition) 

Но если я использую навигацию из MyDepartment, я получаю IEnumerable<Employee>, который на самом деле является System.Linq.WhereEnumerableIterator<Employee> (частный класс в System.Linq.Enumerable):

var employees = MyDeparment.Employees.Where(e => e.SomeCondtition) 

в коде, приведенном ниже, я сильно использовать employees в нескольких запросах LINQ (Where, OrderBy, First, Sum и т.д.)

Должен ли я принимать во внимание, какой метод запроса я использую? Будет ли разница в производительности? Использует ли последнее отсроченное исполнение? Лучше ли практика? Или это не имеет значения?

Я спрашиваю это потому, что после установки Reshaper 6, я получаю много возможного многократного перечисления IEnumerable предупреждений при использовании последнего метода, но ни когда не используя прямые запросы. Я использую последний метод чаще, просто потому, что писать гораздо чище, и мне интересно, действительно ли это на самом деле оказало пагубное влияние!

ответ

2

Существует очень большая разница.

Если вы используете первый подход, вы можете создать дерево выражений, и вы можете добавлять другие выражения, и только при выполнении запроса (отложенное выполнение) дерево выражений будет преобразовано в SQL и выполнено в базе данных. Поэтому, если вы используете свой первый пример и добавите .Sum что-то, что вы действительно выполните операцию в базе данных, оно перенесет только одно число обратно в ваше приложение. Это linq-to-entity.

Второй пример используется в коллекции памяти. Свойство навигации не представляет IQueryable (дерево выражений). Все команды linq обрабатываются как linq-to-objects = все записи, представляющие связанные данные в свойстве навигации, должны быть сначала загружены из базы данных в ваше приложение, и все операции выполняются в памяти вашего сервера приложений. Вы можете загружать навигационное свойство с нетерпением (используя Include), явно (используя Load) или лениво (это делается автоматически, когда вы впервые получаете доступ к свойству, если включена ленивая загрузка). Поэтому, если вы хотите иметь сумму чего-то такого сценария, вам необходимо загрузить все данные из базы данных, а затем выполнить операцию локально.

+0

Спасибо за это. Должен ли я вообще избегать навигационных свойств при использовании в этом контексте или это было бы эквивалентно просто для того, чтобы я вызывал CreateSourceQuery() для перечислимых свойств навигации? – Ross

+0

Как только вы используете 'CreateSourceQuery', вы снова используете IQueryable, который в порядке. Сами свойства навигации не предназначены для запросов. Они предназначены для работы со связанными объектами. –

+0

Является ли свойство навигации имеющими какие-либо преимущества перед выполненными запросами для фильтрации? – ManirajSS

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

  • Нет связанных вопросов^_^