Using TSQL stored procedures, dynamic queries were a cinch. For example, say I had a reporting application that optionally asked for archived records. The stored procedure would look like so:
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, '') + '
'
Barring any silly typos, that's how I've done dynamic queries before. For each new optional parameter I add another conditional block and add the necessary join and where code (and adapt the model if I need to also add ordering, etc.). I'm trying to work out how to do this in Entities but am having a rough time of it.
Most links I've found (http://naspinski.net/post/Writing-Dynamic-Linq-Queries-in-Linq-to-Entities.aspx in particular) show how to look for a dynamically changing string using this bit of code:
var data = ctx.table.Where(b => b.branch_id == 5 || b.display == "Hello");
I don't think this works in my example, as I need to dynamically add n-number of additional where clauses and possibly joins depending on what variables are passed in.
I had hoped I could do something simple like:
var query =
(from t in ctx.Table
select t);
if (optionalvar1)
{
query = query.Join('etc');
query = query.Where('etc');
}
But didn't make much progress (can't quite figure out the syntax of either to get them to do what I want.
Any ideas? Am I approaching this wrong? Is there a better, simpler solution? I know at the end of the day I could always have a slew of conditionals checking for each possible set of combinations, then generating the entire LINQ query within that block, but the amount of copy-pasta required there is frustrating.