介绍
System.Linq.Dynamic.Core 是一个扩展库,用于在运行时动态构建 LINQ 查询,支持字符串形式的表达式解析和动态查询操作。它是 .NET 的一个强大工具,适合处理需要灵活定义查询逻辑的场景,例如动态过滤、排序、投影等。
与C# Linq 区别
System.Linq.Dynamic.Core 查询方式、写法 与 C# linq 不同,而是更接近 SQL
如:分组求和、平均数时,可以正常处理数据,不会像 C# Linq 那样报错
安装
通过 nuget 安装 System.Linq.Dynamic.Core
注意: System.Linq.Dynamic 废弃
导入
添加:
using System.Linq;
using System.Linq.Dynamic.Core;
查询
准备
封装对象:
class Person
{
public string Name { set; get; }
public int Age { set; get; }
public string Gender { set; get; }
public object Data { set; get; }
public override string ToString() => Name;
}
初始化数据:
static List<Person> init()
{
List<Person> personList = new List<Person>
{
new Person
{
Name = "李雷", Age = 18, Gender = "Male", Data = 1.5,
},
new Person
{
Name = "张三", Age = 19, Gender = "Male", Data = null,
},
new Person
{
Name = "韩梅梅", Age = 17,Gender = "Female", Data = 7*1.0
}
};
return personList;
}
条件查询
public static void s1条件()
{
List<Person> list = init();
// 使用动态 Where
var result = list.AsQueryable().Where("Age > 18");
foreach (var person in result)
{
Console.WriteLine($"{person.Name} - {person.Age}");
}
}
排序
public static void s2排序()
{
List<Person> list = init();
// 使用动态 OrderBy
var result = list.AsQueryable().OrderBy("age desc");
foreach (var person in result)
{
Console.WriteLine($"{person.Name} - {person.Age}");
}
}
指定select查询列
public static void s4Select()
{
List<Person> list = init();
// 使用动态 Select
var result = list.AsQueryable().
Select(
@"new (
Name as name,
Age as age
)"
) ;
foreach (dynamic person in result)
{
Console.WriteLine($"{person.name} - {person.age}");
}
}
指定select查询列2
返回 List
public static void s3Select()
{
List<Person> list = init();
// 使用动态 Select
var result = list.AsQueryable().
Select(
@"new (
Name as name,
Age as age
)"
).ToDynamicList(); ;
foreach (var person in result)
{
Console.WriteLine($"{person.name} - {person.age}");
}
}
分组
分组统计
public static void s4GroupBy()
{
List<Person> list = init();
var groupedData = list.AsQueryable()
.GroupBy("Gender")
.Select("new(Key ,average(Age) as avgAge )");
foreach (dynamic group in groupedData)
{
Console.WriteLine($"性别: {group.Key}, 平均年龄: {group.avgAge}");
}
}
分组统计2
返回 List
public static void s5GroupBy()
{
List<Person> list = init();
var groupedData = list.AsQueryable()
.GroupBy("Gender")
.Select("new(Key ,average(Age) as avgAge,sum(Age) as sumAge )")
.ToDynamicList();
foreach (var group in groupedData)
{
Console.WriteLine($"性别: {group.Key}, 平均年龄: {group.avgAge},年龄和:{group.sumAge}");
}
}
多列分组
var result = list.AsQueryable()
.GroupBy("new (c0 , c1 ) ","it")
.Select("new (it.Key.c0 , it.Key.c1, Sum( as (c2, \"double?\" )) as sumc2 )");
解释: c0、c1、c2 是 list 中元素的属性,都是 object 类型,所以要将 c2 转成 double 类型
别名
var result = list.AsQueryable()
.GroupBy("new (c0 as my0 , c1 as my1) ", "it")
.Select("new (it.Key.my0 , it.Key.my1, Sum( as (c2, \"double?\" )) as sumc2 )");
解释: c0、c1、c2 是 list 中元素的属性,都是 object 类型,所以要将 c2 转成 double 类型
https://www.leavescn.com/Articles/Content/3513
类型转换
类型转换
类型转换非常有用,可以对字符串类型的值转成你想要的类型,以满足更灵活场景的动态特性。
也支持复杂类型的转换,参考 附1中的Cast and OfType
//postgres数据库会转成: "Value"::int > 0
var count = qry.Count("As(Value, \"int?\") >0");
类型转换、分组统计(接上面例子)
public static void s6GroupBy()
{
List<Person> list = init();
var groupedData = list.AsQueryable()
.GroupBy("Gender")
.Select("new(Key ,average(Age) as avgAge,sum( as(Data,\"double?\")) as sumData ,average( as(Data,\"double?\") ) as avgData )")
.ToDynamicList();
foreach (var group in groupedData)
{
Console.WriteLine($"性别: {group.Key}, 平均年龄: {group.avgAge},sumData:{group.sumData},avgData:{group.avgData}");
}
}
https://www.cnblogs.com/pains/p/18563616