Немного опоздал к игре, но я нашел этот пост, когда искал что-то еще, и подумал, что я отправлю ответ на фундаментальные вопросы в оригинальном посте, который в основном сводится к «LINQ to SQL позволяет Expression[x], но EF нет ".
Ответ заключается в том, что поставщик запросов (код, который переводит ваше дерево выражений LINQ в нечто, что фактически выполняется и возвращает перечисляемый набор вещей), принципиально отличается междуL2S и EF.Чтобы понять почему, вы должны понимать, что еще одно фундаментальное отличие между L2S и EF состоит в том, что L2S основан на таблицах, а EF основан на объектных моделях.Другими словами, EF работает с концептуальными моделями сущностей и знает, что базовая физическая модель (таблицы БД) не обязательно отражает концептуальные сущности.Это потому, что таблицы нормализованы / денормализованы, и имеют странные способы работы с обобщением типа сущности (наследование).Таким образом, в EF у вас есть представление о концептуальной модели (объектах, с которыми вы кодируете в VB / C # и т. Д.) И сопоставлении с физическими базовыми таблицами, которые составляют ваши концептуальные сущности.L2S не делает этого.Каждая «модельная сущность» в L2S является строго одной таблицей, с точно такими же полями таблицы, как есть.
Пока что это само по себе не объясняет проблемы в первоначальном посте, но, надеюсь,, вы можете начать понимать, что принципиально, EF - это не L2S + или L2S v4.0.Это совершенно другой вид продукта (настоящий ORM), даже если есть некоторое совпадение в том факте, что оба используют LINQ для получения данных базы данных.
Еще одно интересное отличие заключается в том, что EF был построен с нулябыть независимым от БД, тогда как L2S работает только против MS SQL Server (хотя любой, кто достаточно глубоко изучил код L2S, увидит, что есть некоторые основания, позволяющие использовать разные БД, но в итоге он был привязан к MS SQL Serverтолько).Это различие также играет большую роль в том, почему некоторые выражения работают в L2S LINQ, но не в EF LINQ.Поставщик запросов EF имеет дело с каноническими выражениями БД, что на простом английском языке означает выражения LINQ, которые имеют эквиваленты SQL-запросов практически во всех реляционных базах данных.Базовый EF-механизм (поставщик запросов) преобразует выражения LINQ в эти канонические выражения DB, а затем передает дерево канонических выражений конкретному поставщику DB (скажем, поставщику EF Oracle или MySQL), где оно преобразуется в специфичный для продукта SQL.Здесь вы можете увидеть, как эти канонические выражения должны переводиться отдельными поставщиками продуктов: http://msdn.microsoft.com/en-us/library/ee789836.aspx
Кроме того, EF позволяет использовать некоторые функции БД (функции хранилища) для конкретных продуктов в виде выражений через расширения.Базовые поставщики продуктов и услуг отвечают как за предоставление, так и за их перевод.
В этом случае EF допускает только выражения, являющиеся каноническими выражениями БД, или функции, специфичные для магазина, потому что all выражения в дереве преобразуются в SQL для выполнения в БД.
Разница с L2S заключается в том, что L2S передает все возможные выражения в БД из своего ограниченного генератора SQL, а затем выполняет любые выражения, которые могутне переводить в SQL для материализованного набора объектов, который возвращается.Хотя это упрощает использование L2S, но вы не видите, что половина ваших выражений фактически не попадает в БД в виде SQL, и это может привести к некоторым действительно неэффективным запросам, возвращающим большие наборы данных, которые затем повторяются.снова в памяти CLR с обычным объектом LINQ, действующим против них для других выражений, которые L2S не может превратить в SQL.
Вы получаете те же самые эффекты в EF, используя EF для возврата материализованных данных в наборы объектов в памяти, а затем используя дополнительные операторы LINQ для этого набора в памяти - как это делает L2S, но в этом случае вы просто сделать это явно, точно так же, как когда вы говорите, что должны вызывать .First () перед использованием не-DB-канонического выражения. Точно так же вы можете вызвать .ToArray () или .ToList () перед использованием дополнительных выражений, которые нельзя превратить в SQL.
Еще одно большое отличие состоит в том, что в EF сущности должны использоваться как единое целое. Реальные модельные объекты представляют собой концептуальные объекты, которые обрабатываются в целом. Например, у вас никогда не бывает половины пользователей. Пользователь - это объект, состояние которого зависит от всех полей. Если вы хотите вернуть частичные объекты или плоское объединение нескольких объектов, вам нужно определить проекцию (то, что EF называет сложным типом), или вы можете использовать некоторые из новых функций POCO 4.1 / 4.2 / 4.3.