我尝试在 LINQ 查询中使用 expandoobjects 来查询在运行时创建的属性,例如来自 csv 文件的标题。如果直接在代码中键入 LINQ 查询,则一切正常,如示例所示:
// 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);
然后我尝试从命令行读取查询并使用稍微修改过的评估 linq 编译器版本创建动态 LINQ 查询。
string expression = System.Console.ReadLine();
LinqCompiler lc = new LinqCompiler(expression);
lc.AddSource<ExpandoObject>("hans", hans);
IEnumerable<ExpandoObject> klaus = (IEnumerable<ExpandoObject>)lc.Evaluate();
只要我不使用 WHERE 或 ORDER BY 语句,一切都很好,但如果查询中包含任何 WHERE 或 ORDER BY,我在 linq 编译器中编译 codedom 代码时会出错:CS1963: An expression树可能不包含动态操作。
查询代码是使用以下行创建的:
doRequestMethod.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(Query)));
我想 codedom 编译器正在以某种不同于解析直接键入 LINQ 查询的方式构建表达式树。任何让它工作的想法都会被认可,包括为运行时生成的对象动态创建查询的其他想法。