I tried to use expandoobjects in LINQ queries to have the ability to query against properties that are created during runtime, for example the headers from a csv file. It all worked fine if typing the LINQ query direct in the code as in the example:
// initialize testdata
List<ExpandoObject> hans = new List<ExpandoObject>();
string[] names = {"Apfel", "Birne", "Banane", "Orange"};
int[] ids = { 1, 2, 3, 4 };
for (int i = 0; i < 4; i++)
{
dynamic horst = new ExpandoObject();
((IDictionary<string, object>)horst).Add("Fruit", names[i]);
((IDictionary<string, object>)horst).Add("ID", ids[i]);
hans.Add(horst);
}
// try some LINQ queries, both are working as intended
var klaus = from dynamic x in hans where x.ID < 3 select x;
//var klaus = hans.Where(x => x.ID < 3).Select(x => x);
Then i tried to read the query from the commandline and create a dynamic LINQ query using a slighty modified version of the evaluant linq compiler.
string expression = System.Console.ReadLine();
LinqCompiler lc = new LinqCompiler(expression);
lc.AddSource<ExpandoObject>("hans", hans);
IEnumerable<ExpandoObject> klaus = (IEnumerable<ExpandoObject>)lc.Evaluate();
As long as as i don´t use WHERE or ORDER BY statements, everything is fine, but if any WHERE or ORDER BY is included in the query, i get an error when compiling the codedom code in the linq compiler: CS1963: An expression tree may not contain a dynamic operation.
The code for the query is created using the following line:
doRequestMethod.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(Query)));
I suppose that the codedom compiler is building the expression tree in some way different to the way a direct typed in LINQ query is parsed. Any idea to get this to work would be appretiated, including other ideas to dynamically create queries for runtime-generated objects.