使用Expression 生成sql update语句的时候遇到了个问题 ,Expression<Action<T>> la 这个委托里面老获取不到 引用类型的值,甚至连变量的值都不好获取 只能获取常量(ConstantExpression)的值
折腾一晚上之后终于找到解决方案
if (sqlWhere == "")
return 0;
Type type = typeof(T);
var param = ReflectionUtil.CreateInstance(typeof(T));
string result = string.Empty;
MemberInitExpression binding = (MemberInitExpression)fieldAndValueMap.Body;
List<string> member = new List<string>();
foreach (MemberAssignment item in binding.Bindings)
{
string update = item.Member.Name + "=@" + item.Member.Name;
member.Add(update);
PropertyInfo property = type.GetProperty(item.Member.Name);
ConstantExpression ce = null;
var ExpressionType = item.Expression.GetType().Name;
//UnaryExpression 有问题
if (ExpressionType == "PropertyExpression")//对象属性
{
//妈的 这里居然要转两次
MemberExpression innerMember0 = (MemberExpression)item.Expression;
MemberExpression innerMember = (MemberExpression)(innerMember0).Expression;
ce = (ConstantExpression)innerMember.Expression;
PropertyInfo outerProp = (PropertyInfo)item.Member;
FieldInfo innerField = (FieldInfo)innerMember.Member;
object innerObj = ce.Value;
object outerObj = innerField.GetValue(innerObj);
object value = outerProp.GetValue(outerObj, null);
ReflectionUtil.SetPropertyNotBF(param, item.Member.Name, value);
}
else if (ExpressionType == "FieldExpression")//字段变量
{
MemberExpression innerMember = (MemberExpression)item.Expression;
ce = (ConstantExpression)innerMember.Expression;
PropertyInfo outerProp = (PropertyInfo)item.Member;
FieldInfo innerField = (FieldInfo)innerMember.Member;
object innerObj = ce.Value;
object outerObj = innerField.GetValue(innerObj);
ReflectionUtil.SetPropertyNotBF(param, item.Member.Name, outerObj);
}
else if (ExpressionType == "UnaryExpression")//
{
var innerMember = ((UnaryExpression)item.Expression).Operand as MemberExpression;
ce = (ConstantExpression)innerMember.Expression;
FieldInfo innerField = (FieldInfo)innerMember.Member;
object innerObj = ce.Value;
object outerObj = innerField.GetValue(innerObj);
ReflectionUtil.SetPropertyNotBF(param, item.Member.Name, outerObj);
}
else//常量参数
{
ce = (ConstantExpression)item.Expression;
ReflectionUtil.SetPropertyNotBF(param, item.Member.Name, ce.Value);
}
}
result = string.Join(",", member);
var sql = string.Format("UPDATE {0} SET {1} WHERE {2}", TableName, string.Join(",", member), sqlWhere);
return DapperDbSessionFactory.GetCurrentDbSession(transaction).Connection.Execute(sql, param, transaction);
可以参考 SqlSugar
然后可以这样调用BatchUpdateFields(n => new Entity() { name= entity.name, age= entity.age, sex= entity.sex, Id = entity.Id }, " Id=@Id", null)
这样可以值更新部分字段
主要是 PropertyExpression和FieldExpression 连个类型无法和常量一样取值 需要进行转换