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

如何通过反射结合EF Core的ExecuteUpdate()更新数据库?代码报错求助

问题描述

尝试通过反射结合Entity Framework Core的ExecuteUpdate()方法更新数据库,编写的代码如下:

public async Task<bool> UpdateUserProperty(string username, string property, object value)
{
    // Using Reflection:
    _TMSContext.Users
   .Where(u => u.UserName == username)
   .ExecuteUpdate(s => s.SetProperty(u => u.GetType().GetProperty(property), value));

    // Trying to use reflection to accomplish this:
    //_TMSContext.Users
    //    .Where(u => u.UserName == username)
    //    .ExecuteUpdate(s => s.SetProperty(u => u.ForceChangePasswordInd, value));

    return true;
}

运行代码时抛出错误:

System.InvalidOperationException: 'The LINQ expression 'DbSet()
.Where(u => u.UserName == __username_0)
.ExecuteUpdate(s => s.SetProperty(
propertyExpression: u => u.GetType().GetProperty(__property_1),
valueExpression: __value_2))' could not be translated. Additional information: The following lambda argument to 'SetProperty' does not represent a valid property to be set: 'u => u.GetType().GetProperty(__property_1)'

解决方案

EF Core无法将反射调用(如u.GetType().GetProperty(property))翻译为SQL,因为ExecuteUpdate需要明确的属性访问表达式来生成更新语句。需手动构建属性访问的表达式树来实现动态更新:

实现代码

using System.Linq.Expressions;

public async Task<bool> UpdateUserProperty(string username, string property, object value)
{
    // 验证目标属性是否存在
    var propertyInfo = typeof(User).GetProperty(property);
    if (propertyInfo == null)
    {
        return false;
    }

    // 构建参数表达式:u => u
    var userParam = Expression.Parameter(typeof(User), "u");
    // 构建属性访问表达式:u => u.[指定属性]
    var propertyAccess = Expression.Property(userParam, propertyInfo);
    var propertyLambda = Expression.Lambda(propertyAccess, userParam);

    // 构建SetProperty的调用表达式
    var setPropertyMethod = typeof(SetPropertyCalls<User>)
        .GetMethod(nameof(SetPropertyCalls<User>.SetProperty))
        .MakeGenericMethod(propertyInfo.PropertyType);

    var updateLambda = Expression.Lambda(
        Expression.Call(
            Expression.Parameter(typeof(SetPropertyCalls<User>), "s"),
            setPropertyMethod,
            propertyLambda,
            Expression.Constant(value, propertyInfo.PropertyType)
        ),
        Expression.Parameter(typeof(SetPropertyCalls<User>), "s")
    );

    // 执行更新并获取受影响行数
    var affectedRows = await _TMSContext.Users
        .Where(u => u.UserName == username)
        .ExecuteUpdateAsync(updateLambda);

    return affectedRows > 0;
}

关键说明

  • ExecuteUpdate仅接受直接的属性访问Lambda,反射调用无法被EF Core解析为SQL,必须通过表达式树生成符合要求的表达式。
  • 添加属性存在性校验可避免因传入无效属性名导致的异常。
  • 最终通过构建的表达式树,EF Core能正确生成对应的UPDATE SQL语句,实现动态更新指定属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:35:54