C#之Expression表达式树实例

C#之Expression表达式树实例

简介

Expression表达式树是C#中一种强大的语言特性,可以通过表达式树实现动态构建Lambda表达式,让开发者可以在运行时动态的创建查询、过滤、排序等功能,大大提高了程序的灵活性。本文将详细讲解如何使用Expression表达式树实现常见的功能。

示例一:动态查询

如下是一个简单的Person类:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

现在我们需要根据Person对象的Name和Age属性进行查询,如果使用Linq语句,那么需要手动指定Name和Age的属性名:

List<Person> persons = new List<Person>
{
    new Person {Name = "张三", Age = 20},
    new Person {Name = "李四", Age = 30},
    new Person {Name = "王五", Age = 40},
};

// 查询Name为李四的Person
var person = persons.FirstOrDefault(p => p.Name == "李四");

// 查询Age大于等于30的Person列表
var personList = persons.Where(p => p.Age >= 30).ToList();

这种做法需要手动指定属性名,代码可读性和可维护性都不高,使用Expression表达式树可以很好的解决这个问题。我们定义一个动态查询的方法,可以根据传入的属性名称和属性值进行查询:

public static class PersonExtensions
{
    public static IQueryable<Person> WhereByNameAndAge(this IQueryable<Person> query, string name, int age)
    {
        var parameter = Expression.Parameter(typeof(Person), "p");
        var propertyExpr1 = Expression.Property(parameter, nameof(Person.Name));
        var propertyExpr2 = Expression.Property(parameter, nameof(Person.Age));
        var constantExpr1 = Expression.Constant(name, typeof(string));
        var constantExpr2 = Expression.Constant(age, typeof(int));
        var conditionExpr1 = Expression.Equal(propertyExpr1, constantExpr1);
        var conditionExpr2 = Expression.GreaterThanOrEqual(propertyExpr2, constantExpr2);
        var andExpr = Expression.AndAlso(conditionExpr1, conditionExpr2);
        var lambdaExpr = Expression.Lambda<Func<Person, bool>>(andExpr, parameter);
        return query.Where(lambdaExpr);
    }
}

这个方法接受一个IQueryable类型的查询对象,以及两个参数name和age。通过使用Expression方法构造Expression表达式树,然后返回一个查询结果。使用此方法进行查询:

var person = persons.WhereByNameAndAge("李四", 30).FirstOrDefault();
var personList = persons.WhereByNameAndAge("", 30).ToList();

示例二:动态排序

如下是一个简单的Product类:

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

现在需要根据Product的Price属性进行排序,但是排序的方向(升序或者降序)是不确定的,我们需要动态构建Lambda表达式。如果使用Linq语句进行排序,需要手动判断排序方向:

List<Product> products = new List<Product>
{
    new Product {Name = "苹果", Price = 10},
    new Product {Name = "香蕉", Price = 5},
    new Product {Name = "橘子", Price = 20},
};

// 升序
var sortedProductsAsc = products.OrderBy(p => p.Price).ToList();

// 降序
var sortedProductsDesc = products.OrderByDescending(p => p.Price).ToList();

使用Expression表达式树可以强制指定排序方向,实现更加灵活的排序方法:

public static class ProductExtensions
{
    public static IQueryable<Product> OrderByPrice(this IQueryable<Product> query, bool isAscending)
    {
        var parameterExpr = Expression.Parameter(typeof(Product), "p");
        var propertyExpr = Expression.Property(parameterExpr, nameof(Product.Price));
        var lambdaExpr = Expression.Lambda(propertyExpr, parameterExpr);
        var methodName = isAscending ? "OrderBy" : "OrderByDescending";
        var methodExpr = Expression.Call(
            typeof(Queryable),
            methodName,
            new Type[] {query.ElementType, typeof(decimal)},
            query.Expression,
            lambdaExpr
        );
        return query.Provider.CreateQuery<Product>(methodExpr);
    }
}

该方法接收IQueryable类型的查询对象以及一个布尔类型的参数isAscending,该参数指定排序方向。通过Expression构造表达式树,然后使用反射调用OrderBy方法进行排序,最后返回排序结果。

var sortedProductsAsc = products.OrderByPrice(true).ToList();
var sortedProductsDesc = products.OrderByPrice(false).ToList();

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#之Expression表达式树实例 - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • C#如何在窗体程序中操作数据库数据

    你好,操作数据库是窗体程序的一个关键功能之一,C#通过ADO.NET技术来实现数据库连接,并且提供了丰富的工具和类实现数据的访问、读写和更新等操作。下面是C#在窗体程序中操作数据库数据的完整攻略。 步骤一:创建数据库连接 连接数据库是操作数据库的第一步,C#通过SqlConnection类来创建数据库连接,构造方法的参数是连接字符串,其中包含数据库的地址、用…

    C# 2023年5月15日
    00
  • C#字符串使用密钥进行加解密

    接下来我将为你详细讲解C#字符串使用密钥进行加解密的完整攻略。 首先,我们需要了解几个基本的概念:加密、解密、密钥。在此之前,我们需要知道需要使用到的命名空间:System.Security.Cryptography。 加密和解密 加密是指将信息转换为密文的过程,解密是指将密文恢复成信息的过程。在这个过程中,需要使用特定的算法对信息进行加密和解密。我们在C#…

    C# 2023年6月8日
    00
  • ASP.NET Core读取配置文件

    ASP.NET Core 读取配置文件是一种非常常见的操作,可以用于配置应用程序的行为。以下是 ASP.NET Core 基础之读取配置文件的完整攻略: 步骤一:创建 ASP.NET Core 应用程序 首先,需要一个 ASP.NET Core 应用程序。可以使用以下命令在 Visual Studio 中创建一个 ASP.NET Core 应用程序: 打开 …

    C# 2023年5月17日
    00
  • asp.net生成静态后冗余代码,去掉viewstate生成的代码

    下面我将为你详细讲解如何在ASP.NET中生成静态页面时去掉ViewState生成的冗余代码。 示例一:使用Web.config配置 打开你的ASP.NET Web应用程序的Web.config文件 添加以下配置节到元素下 <system.web> <pages> <tagPrefix="MyCustomPrefix&…

    C# 2023年5月31日
    00
  • .NET Core使用Eureka实现服务注册

    下面我将详细讲解”.NET Core使用Eureka实现服务注册”的完整攻略。 什么是Eureka Eureka是Netflix开源的一个提供服务治理的组件。通过Eureka,服务提供者将自己的信息(比如IP、端口、路径等)注册到Eureka上,服务消费者从Eureka上获取服务提供者的信息,然后消费者就可以根据这些信息来请求服务。这个过程中,Eureka扮…

    C# 2023年6月3日
    00
  • C#利用反射实现多数据库访问

    C#利用反射实现多数据库访问的完整攻略指的是使用C#编程语言,通过反射技术实现对多种不同的数据库的访问操作。在开发过程中,我们可以针对不同的数据库类型编写不同的代码。下面是整个过程的具体步骤: 添加必要的引用和命名空间:在使用反射进行数据库访问操作之前,我们需要在引用中添加 System.Reflection 和 System.Data 命名空间。添加这些命…

    C# 2023年6月1日
    00
  • JS中substring与substr的用法

    JS中的substring和substr是用来截取字符串的方法,这两个方法虽然都能实现截取字符串的功能,但是它们有一些不同之处。以下是详细的讲解: substring方法 substring方法是用来截取字符串中的一部分,它接受两个参数,分别是起始位置和结束位置(不包括结束位置的字符)。如果只传入了一个参数,则从该参数所在位置截取到字符串末尾。 以下是一个示…

    C# 2023年6月7日
    00
  • C# [ImportDll()] 知识小结

    C# [ImportDll()] 知识小结攻略 1. 什么是 [ImportDll()] [ImportDll()] 是 C# 中的一个特性,它用于在程序中引入外部的 DLL 库,以便使用其提供的函数或方法。通常情况下,这些 DLL 库由其他编程语言(如 C/C++)等编写,而 C# 使用 [ImportDll()] 将其加入到自己的代码中。 2. 如何使用…

    C# 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部