EF создает EntityCollection, но я (думаю, я) хочу IQueryable - PullRequest
9 голосов
/ 30 ноября 2010

У меня есть объект A с простым свойством навигации B. Для любого данного экземпляра A мы ожидаем несколько связанных тысяч экземпляров B.

Не бывает случаев, когда я называю что-то вроде:

foreach(var x in A.B) { ... }

Вместо этого я только заинтересован в выполнении агрегатных операций, таких как

var statY = A.B.Where(o => o.Property == "Y");
var statZ = A.B.Where(o => o.CreateDate > DateTime.Now.AddDays(-1));

Насколько я могу судить, EF создает тысячи ссылок на B и выполняет эти операции в памяти. Это потому, что свойства навигации используют EntityCollection. Вместо этого я бы хотел, чтобы эти запросы выполнялись на уровне SQL, если это возможно.

В настоящее время я предполагаю, что свойства навигации могут быть неправильным способом. Я не привязан к EF, поэтому я открыт для других подходов. Но мне было бы очень интересно узнать правильный способ сделать это в EF, если это возможно.

(я использую EF4.)

Ответы [ 2 ]

12 голосов
/ 30 ноября 2010

CreateSourceQuery , кажется, добивается цели.

Итак, мои примеры теперь будут:

var statY = A.B.CreateSourceQuery().Where(o => o.Property == "Y");
var statZ = A.B.CreateSourceQuery().Where(o => o.CreateDate > DateTime.Now.AddDays(-1));
0 голосов
/ 30 ноября 2010

Есть одна вещь, которую вы должны знать.Члены, производные от IQueryable <>, выполняются на сервере, а не в памяти.Члены, которые являются производными от IEnumerable <>, выполняются в памяти.Например,

var someEntities = db.SomeEntities; <-- returns an IQueryable<> object. no data fetched. SomeEntities table may contain thousands of rows, but we are not fetching it yet, we are just building a query.
someEntities = someEntities.Where(s => s.Id > 100 && s.Id < 200); <-- creates expression tree with where statement. The query is not executed yet and data is not fetched on the client. We just tell EF to perform a where filter when query will execute. This statement too returns an IQueryable<> object.
var entities = someEntities.AsEnumerable(); <-- here we tell EF to execute query. now entities will be fetched and any additional linq query will be performed in memory.

Вы также можете получить данные, используя foreach, вызывая ToArray () или ToList <>.

Надеюсь, вы понимаете, о чем я, и извините за мой английский:)

...