EF создает EntityCollection, но я (думаю, я) хочу IQueryable
У меня есть сущность 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 ответа
CreateSourceQuery, кажется, делает свое дело.
Так что мои примеры теперь будут:
var statY = A.B.CreateSourceQuery().Where(o => o.Property == "Y");
var statZ = A.B.CreateSourceQuery().Where(o => o.CreateDate > DateTime.Now.AddDays(-1));
Есть одна вещь, которую вы должны знать. Члены, производные от 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<>.
Надеюсь, вы понимаете, о чем я, и извините за мой английский:)