You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在未知属性类型时无分支创建NHibernate泛型Lambda表达式?

动态创建泛型Lambda表达式(Func<User, T>)用于NHibernate UpdateBuilder.Set

我需要根据属性信息动态创建泛型Lambda表达式。目前通过反射获取了User类的Counter属性,能构建表达式参数和属性表达式,但生成的是固定的Func<User, object>类型,实际需要根据属性的真实类型(如int、string、bool等)创建对应的Func<User, T>,并传入NHibernate的UpdateBuilder.Set方法来更新数据库字段。

请问有没有办法在未知属性类型的情况下,不用针对每种属性类型写分支判断代码,就能创建出对应的泛型Lambda表达式?


可以通过表达式树结合反射动态调用泛型方法实现,完全不需要写类型分支判断。核心思路是先构建属性访问的表达式主体,再动态生成对应类型的Func<TSource, TProperty>委托。

实现步骤与代码示例

// 1. 通过反射获取目标属性(示例为User类的Counter属性)
PropertyInfo propertyInfo = typeof(User).GetProperty("Counter");

// 2. 构建表达式基础节点
ParameterExpression param = Expression.Parameter(typeof(User), "x"); // 对应Lambda的输入参数x
MemberExpression propertyAccess = Expression.Property(param, propertyInfo); // 对应x.Counter的表达式

// 3. 动态获取并调用Expression.Lambda的泛型版本
MethodInfo lambdaGenericMethod = typeof(Expression).GetMethods()
    .First(m => m.Name == "Lambda" && m.ContainsGenericParameters && m.GetParameters().Length == 2)
    .MakeGenericMethod(typeof(Func<,>).MakeGenericType(typeof(User), propertyInfo.PropertyType));

// 4. 创建并编译泛型Lambda表达式
Delegate propertyFunc = lambdaGenericMethod.Invoke(null, new object[] { propertyAccess, new[] { param } });

// 5. 直接传入NHibernate的UpdateBuilder.Set方法
updateBuilder.Set((dynamic)propertyFunc, newValue);

关键说明

  • 这段代码会自动根据属性的真实类型(如int、string)生成对应的Func<User, T>委托,无需手动判断类型分支。
  • 如果需要复用逻辑,可以封装成通用方法:
    public static Delegate CreatePropertyAccessor<TSource>(PropertyInfo propertyInfo)
    {
        ParameterExpression param = Expression.Parameter(typeof(TSource), "x");
        MemberExpression propertyAccess = Expression.Property(param, propertyInfo);
        MethodInfo lambdaMethod = typeof(Expression).GetMethods()
            .First(m => m.Name == "Lambda" && m.ContainsGenericParameters && m.GetParameters().Length == 2)
            .MakeGenericMethod(typeof(Func<,>).MakeGenericType(typeof(TSource), propertyInfo.PropertyType));
        return lambdaMethod.Invoke(null, new object[] { propertyAccess, new[] { param } });
    }
    
  • 利用dynamic关键字可以直接将生成的委托传入UpdateBuilder.Set,NHibernate会自动处理类型匹配。

内容的提问来源于stack exchange,提问作者user3132295

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:54:17