Используя хранимые процедуры TSQL, динамические запросы были простыми.Например, скажем, у меня было приложение для составления отчетов, которое опционально запрашивало архивные записи.Хранимая процедура будет выглядеть так:
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, '') + '
'
Запрет на любые глупые опечатки, вот как я делал динамические запросы раньше.Для каждого нового необязательного параметра я добавляю еще один условный блок и добавляю необходимый код соединения и кода (и адаптирую модель, если мне нужно также добавить порядок и т. Д.).Я пытаюсь выяснить, как это сделать в сущностях, но у меня трудные времена.
Большинство найденных мной ссылок (в частности, 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");
Я не думаю, что это работает в моем примере, поскольку мне нужно динамически добавлять n-число дополнительных предложений where и, возможно, объединения в зависимости от того, какие переменные являютсяпередал.
Я надеялся, что смогу сделать что-то простое, например:
var query =
(from t in ctx.Table
select t);
if (optionalvar1)
{
query = query.Join('etc');
query = query.Where('etc');
}
Но не добился большого прогресса (не могу понять синтаксис того, чтобы заставить ихделай то, что я хочу.
Любые идеи? Я подхожу к этому неправильно? Есть ли лучшее, более простое решение? Я знаю, что в конце дня у меня всегда может быть множество условных проверок для каждого возможного наборакомбинаций, а затем генерирует весь запрос LINQ в этом блоке, но количество требуемых копий-макаронных изделий разочаровывает.