C# linq动态 System.Linq.Dynamic.Core 类似拼接SQL语句

介绍

System.Linq.Dynamic.Core 是一个扩展库,用于在运行时动态构建 LINQ 查询,支持字符串形式的表达式解析和动态查询操作。它是 .NET 的一个强大工具,适合处理需要灵活定义查询逻辑的场景,例如动态过滤、排序、投影等。

官网:
https://dynamic-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


原文出处:/show_1GWoX8XBcNA.html