Расширение поколения EF4 SQL

Мы используем EF4 в довольно большой системе и иногда сталкиваемся с проблемами из-за неспособности EF4 преобразовать определенные выражения в SQL. В настоящее время мы или должны сделать некоторые необычные активные действия (DB/код) или просто принять хит производительности и позволить запросу выполняться в оперативной памяти.

Само собой разумеется, ни один из них не идеален, и взломы, которые мы должны были иногда использовать, уменьшают удобочитаемость / пригодность для обслуживания.

То, что мы идеально хотели бы, является способом расширить возможности поколения SQL поставщика EF4 SQL. Очевидно, существуют некоторые вещи как вызовы метода .NET, которые должны будут всегда быть клиентскими, но некоторая функциональность как сравнения даты (например, [Группа к неделям в Linq к Объектам) должна быть выполнимой.

Я Погуглил, но возможно я использую неправильную терминологию в качестве всего, что я получаю, информация о новых возможностях поколения EF4 SQL.

Для такой гибкой и расширяемой платформы я был бы удивлен, не ли это возможно. В моей голове я предполагаю наследоваться [SQL 2008] поставщик и расширить его для обработки дополнительных выражений / подобный в дереве выражений, которое это дано для преобразования в SQL.

Любая справка/указатели ценится.

Мы используем VS2010 Окончательный.Net 4 (неклиентский профиль) и EF4. Приложение находится в ASP.NET и работает в 64-разрядной среде в случае, если это имеет значение.

Обновление: В ответ на некоторые запросы на разъяснение;

Мы используем код, сначала приближаются и имеют консольное приложение, которое создает базу данных и заполняет некоторые ссылочные таблицы.

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

Относительно определенного сценария я боюсь, что не могу дать один из нашего кода, не проходя долгое бюрократическое осуществление - упомянутая выше ссылка является хорошим примером вида вещи, которую мы пытаемся выполнить. В этом примере, реализовывая механизм для разрешения арифметики дат:

DateTime firstDay = GetFirstDayOfFirstWeekOfYear();
var userTimes = from t in context.TrackedTimes
                group t by new {t.User.UserName, WeekNumber = (t.TargetDate - firstDay).Days / 7} into ut
                select new
                {
                    UserName = ut.Key.UserName,
                    WeekNumber = ut.Key.WeekNumber,
                    Minutes = ut.Sum(t => t.Minutes)
                };

Я вижу способ, которым это могло быть выполнено с помощью одного только SQL, но не, как сделать это с помощью LINQ к объектам (Серверная сторона).

6
задан Community 23 May 2017 в 11:55
поделиться

2 ответа

Я бы порекомендовал сначала взглянуть на EntityFunctions (общий) или SqlFunctions (только SQL Server), которые предоставляют множество встроенных функций базы данных. в обычном запросе LINQ to Entities. Если этого недостаточно, вы можете использовать EdmFunctionAttribute для отображения встроенной функции базы данных или определяемой пользователем хранимой процедуры. Третий вариант - попытаться заставить его работать как запрос Entity SQL.

Последнее предложенное вами решение - написание EF-провайдера - довольно тяжеловесное. Возможно, удастся написать поставщик EF, который обертывает существующий поставщик SQL, но вам придется как минимум изменить некоторые деревья выражений на Entity SQL. Очень простые оболочки поставщика EF были выпущены в MSDN Code . Но я бы отнесся к этому как к последнему средству.

9
ответ дан 10 December 2019 в 00:33
поделиться

Преобразование ваших LINQ-запросов на основе .NET в SQL выполняется LINQ To Entities Provider. Я не думаю, что основной процесс перевода/компиляции, который является чрезвычайно сложным, можно расширить. Вам придется писать свой собственный провайдер с нуля.

Я еще не встречал ни одного запроса, который можно представить на SQL и который нельзя выразить на LINQ. Если у вас есть запрос, который трудно написать в виде LINQ-запроса, не рассматривали ли вы возможность использования хранимых процедур вместо него? Было бы полезно, если бы вы привели примеры запросов, которые не конвертируются.

UPDATE:

Другим вариантом является создание расширенных методов расширения, которые используют встроенные выражения для формирования запроса. Вот хороший пример, имитирующий функцию Contains() для выполнения запросов типа "where in":

'Contains()' workaround using Linq to Entities?

1
ответ дан 10 December 2019 в 00:33
поделиться