我想定义一些lambda表达式来表示类实例属性的更新。
我尝试这样写:
Expression<Action<User>> update = user => user.Name = "Joe Foo";
但是我有一个编译错误:
错误CS0832 表达式树可能不包含赋值运算符。
如何使用lambda表示此更新。
编辑
我的目标是使业务服务将更新发送到通用存储库。该存储库可以分析lambda的表达式以构建查询以发送到数据库引擎。
业务服务的示例可以是:
public void DoStuff(String userId, ...)
{
// Business logic here
// ...
// Persist updates determined above
this.repository.Update(
// First parameter is the filter of entities to updates
x => x.Id == userId,
// Next parameters are updates to apply
x => x.FirstName = "John",
x => x.LastName = "Foo",
...);
}
答案 0 :(得分:5)
我想定义一些lambda表达式来表示类实例属性的更新。
您不能总是得到想要的东西。
我们设计了表达式树lambda来表示非变异操作,因此在表达式树中使用=
,+=
,++
等lambda是非法的。
如何用lambda表示此更新?
委托lambda不受此限制;你可以说
Action<User> update = user => user.Name = "Joe Foo";
您能否说说为什么需要这个?可能会有更好的方法来实现您的目标。 您可能会问一个XY问题。这是一个问题,您有一个问题,您有一个不好的解决方案,现在您要问的是有关不好的解决方案的问题,而不是问题。您要解决的问题是什么?
答案 1 :(得分:1)
正如其他人所说,C#不允许在表达式树中使用赋值表达式。
另一种方法是使用new
表达式。这样就可以用一个lambda表示更新:
repository.Update(
x => x.Id == userId, // Where clause
x => new User{ // Update expression
Modified = DateTime.Now,
ModifiedBy = "John",
Amount = x.Amount + 10
}
);
其中x
代表更新表达式中实体的旧状态。
void Update(Expression<Func<T, bool>> filter, Expression<Func<T, T>> update)
如果您不需要引用旧值,则可以使用此简化签名(根据您的评论):
void Update(Expression<Func<T, bool>> filter, Expression<Func<T>> update)
答案 2 :(得分:0)
很难猜出您想如何使用表达式。 如果您想深入思考问题,也许此片段会有所帮助:
var user = new User();
var paramExpr = Expression.Parameter(typeof(User), "user");
var propertyExpression = Expression.Property(paramExpr, "Name");
Expression.Lambda<Action<User>>(
Expression.Assign(
propertyExpression,
Expression.Constant("Joe Foo")
),
new List<ParameterExpression>() { paramExpr }
).Compile()(user);
Console.WriteLine(user.Name); //Joe Foo
在那里,您:
1)定义ParameterExpression
-您的输入;
2)设置如何获取您感兴趣的类的属性(.Name
)
3)最后,定义表达式(并对其进行调用),以执行测试用户变量