Использование хранимых процедур TSQL, динамические запросы были cinch. Например, скажем, у меня было приложение для отчетов, которое, возможно, запросило архивные записи. Хранимая процедура будет выглядеть так:Динамические запросы в LINQ to Entities
DECLARE @sql nvarchar(MAX)
DECLARE @join nvarchar(MAX)
DECLARE @where nvarchar(MAX)
IF @optionalvar1 IS NOT NULL
SET @where = COALESCE(@where, '') +
'AND SomeColumn = ' + @optionalvar1 + ' '
IF @optionalvar2 IS NOT NULL
BEGIN
SET @join = COALESCE(@join, '') +
'LEFT JOIN SomeTable s
ON st.Column = s.Column '
SET @where = COALESCE(@where, '') +
'AND s.SomeColumn = ' + @optionalvar2 + ' '
END
SET @sql =
'
SELECT
*
FROM
StaticTable st
' + COALESCE(@join, '') + '
WHERE
1=1
' + COALESCE(@where, '') + '
'
Запрещая глупые опечатки, вот как я делал динамические запросы раньше. Для каждого нового необязательного параметра я добавляю еще один условный блок и добавляю необходимое соединение и код (и адаптирую модель, если мне нужно также добавить порядок и т. Д.). Я пытаюсь понять, как это сделать в Entities, но у меня время от времени.
Большинство ссылок, которые я нашел (http://naspinski.net/post/Writing-Dynamic-Linq-Queries-in-Linq-to-Entities.aspx в частности) показывают, как искать динамически изменяющуюся строку, используя этот битый код:
var data = ctx.table.Where(b => b.branch_id == 5 || b.display == "Hello");
Я не думаю, что это работает в моем примере, как я нужно динамически добавлять н-число дополнительных, где положения и, возможно, включается в зависимости от того, какие переменные передаются в
Я надеялся, что я мог сделать что-то простое, как:.
var query =
(from t in ctx.Table
select t);
if (optionalvar1)
{
query = query.Join('etc');
query = query.Where('etc');
}
Но не сделал большого прогресса (не могу понять синтаксис, чтобы заставить их делать то, что я хочу.
Любые идеи? Я подхожу к этому неправильно? Есть ли лучшее, более простое решение? Я знаю, что в конце дня у меня всегда может быть множество условных проверок для каждого возможного набора комбинаций, а затем генерация всего запроса LINQ в этом блоке, но количество требуемых там копий-макарон вызывает разочарование.
К сожалению, не в состоянии установить запрос = query.Where был больше опечатка, чем ничего. Моя основная проблема заключается в том, как выразить мой запрос внутри .Where bit. Я не могу работать с объектом «x» - это POCO, содержащий конечный результат моего запроса. Однако в большинстве случаев мне нужно сделать предложение where в других таблицах, участвующих в запросе, но не обязательно возвращаться в конечном объекте. Я уточню вопрос, чтобы уточнить. (Кроме того, переменные, переданные в динамический SQL, происходят из параметризованных запросов в .NET и получают excused с помощью sp_executesql - должно быть нормально (?).) – rake
@rake: Это выглядит так, как будто это только POCO, но LINQ to Entities будет фактически преобразовать их в SQL. Немного о требовании вещей, отсутствующих в остальной части запроса, трудно говорить без конкретного примера. И нет, я не считаю, что ваш динамический SQL безопасен от атак SQL-инъекций только потому, что они параметризованы в .NET.Значение каждого параметра вставляется непосредственно в конечный SQL. Я настоятельно рекомендую вам попробовать. Просто запрос, который включает одну цитату, должен быть достаточным, чтобы дать вам представление о том, что происходит ... –