001 dynamic Linq
引出问题
思考一个场景:
有的时候我们需要根据传入的参数来要求根据哪些字段,对内存中的数据进行分组操作(即分组条件的字段的个数是不确定的),那么我们应该怎么解决这样的问题呢?下面的解决方案,就为我们提供了解决办法.
准备工作
- 我们需要引用System.Linq.Dynamic;
- 我们需要在项目中导入命名空间
System.Linq.Dynamic
上述文件的开源代码下载地址如下:
原文介绍:
偶然看到这项技术的博客地址:
关于group by多字段分组动态表达式生成
翻译:
- 扩展System.Linq.Dynamic以支持对实体框架或任何支持IQueryable的提供程序执行字符串中定义的Lambda表达式。
- 我最初是在Scott Guthrie的博客上看到这个源代码的,当时我正在寻找一种针对实体框架执行动态linq语句的机制。虽然这段代码部分地满足了我的需要,但它和可从NuGet下载的assembly System.Linq.Dynamic.dll都缺少我所需要的确切功能。具体来说,它不允许我对实体对象执行表示为字符串的完整lambda表达式。此外,它缺乏对Take和Union以及许多其他扩展函数的支持,尽管这是我唯一感兴趣的两个函数。因此,我扩展了代码以支持这些特性。我认为我的努力可能会有利于其他人,所以我决定在codeplex上托管它。原始代码是根据Ms PL授权的,根据这个授权,我创建的派生代码库也同样获得了授权。
实体类
public class House
{
public string Name { get; set; }
public string Month { get; set; }
public int DfFee { get; set; }
public int SfFee { get; set; }
}
例程:
List<House> list = new List<House>
{
new House {Name = "张三", Month = "2017-01", DfFee = 100, SfFee = 20},
new House {Name = "张三", Month = "2017-01", DfFee = 20, SfFee = 100},
new House {Name = "张三", Month = "2017-01", DfFee = 10, SfFee = 40},
new House {Name = "李四", Month = "2017-01", DfFee = 67, SfFee = 24},
new House {Name = "李四", Month = "2017-01", DfFee = 672, SfFee = 243}
};
var query = list.AsQueryable()
.GroupBy($"new ({"Name"}, {"Month"})", "it")
.Select("new(it.Key as Key, it as Houses)");
var groupList = (from dynamic g in query select g).ToList();
foreach (var g in groupList)
{
//g.Key 中装载的是分组条件
var temp1 = g.Key.Name;
var temp2 = g.Key.Month;
var temp3 = 0;
var temp4 = 0;
//g.Houses中装载的是可以进行聚合的字段
foreach (var h in g.Houses)
{
temp3 += h.DfFee;
temp4 += h.SfFee;
}
Console.WriteLine($"{temp1} , {temp2} , {temp3} , {temp4}");
}
执行结果: