在DataTable上使用动态LINQ for GroupBy

时间:2010-11-08 21:21:18

标签: c# .net linq c#-3.0

我已经看到了很多方法让动态LINQ适用于.GroupBy,但我看到的每一个似乎都期望一个硬编码实体。我想将以下内容重现为动态LINQ:

//need dynamic LINQ for this
var groupedRows = rows.GroupBy(z => new { make = z["make"], model = z["model"] })
                      .Select(x => x.Key);

我希望能够做到这一点,使整个函数成为一个字符串:

var groupedRows = rows.GroupBy(z => "new { make = z[\"make\"], model = z[\"model\"] }")

我意识到,如果它只是一个普通的实体,我可以做到这一点

mylist.GroupBy(z => new { make = z.make, model = z.model }).Select(x => x.Key);

如果我有那个常规实体,我可以使用Mitsu's dynamic GroupByMany

我正在尝试使用常规数据表(非强类型)。有任何想法吗?

2 个答案:

答案 0 :(得分:0)

我不认为这是可能的;这表明你希望C#编译器在运行时编译你的字符串=)
问题不在于“制造”和“模型”索引器,它是您返回的新实例中的成员;那些只能用Reflection进行文本表示,但我知道LINQ-to-Entities不支持它的功能,不确定普通的LINQ是否会。 您可以使用Reflection解决方案吗? 在我花两个小时试图让它发挥作用之前,我想知道你是否对它好了=)

答案 1 :(得分:0)

好的,我能够使用Mono Compiler as a Service(MCS)在运行时使用反射和编译代码。利用问题Injecting a variable into the Mono.CSharp.Evaluator (runtime compiling a LINQ query from string),我提出了以下解决方案(在该问题的答案中排名第2):

DataTable dt = GetData();
         var dataRows = dt.AsEnumerable();

         //Initializing the evaluator  
         Evaluator.Init(new string[0]); 
          Evaluator.ReferenceAssembly(Assembly.GetAssembly(typeof(DataRow)));
          Evaluator.ReferenceAssembly(Assembly.GetExecutingAssembly());

         Evaluator.Run(@"using System;  
           using System.Linq;  
           using System.Collections.Generic;
           using System.Data;
           using MyNamespace;");

         var func = (Func<DataRow, object>)Evaluator.Evaluate(@"new Func<DataRow,object>(z => new
                {
                    make = z[""make""],
                    model = z[""model""]
                });");

         dataRows.GroupBy(func).Select(x => x.Key);

这样在运行时编译函数,然后在GroupBy中为每一行调用函数。当我需要make或model的值时,我需要使用反射通过我的GetPropertyValue扩展方法获得该值。

即使在遵循Mono Compiler as a Service (MCS)问题之后,我仍然无法让LINQ在MCS中工作,但只是使用它来创建函数我做了我需要做的事情。