我试图用以下格式创建更新函数:
public int Update(
Item Item,
Expression<Func<Item, object>> selector)
如何读取选择器中选择的属性?我需要房产的名字。
这是因为我想使更新功能更智能,所以它只更新必须更新的内容。它用于sql,是一个存储库函数。
谢谢。
更新澄清:
我希望能够像这样调用update:
Update(item, x => new { x.Property1, x.Property2 })
所以ienumerable的表达式不是一个选项,但如果上面是一个更困难的我会这样做。。。
2条答案
按热度按时间guz6ccqo1#
假设您不想验证表达式是否实际返回属性值,这将起作用:
否则,你需要一些类似于这个综合答案的东西。
更新
如果要使用匿名对象,可以执行以下操作:
尽管这很容易被滥用。
8fsztsew2#
如果您不介意将更新代码编写为
Update(item, x => x.Property1, x=> x.Property2 )
,它会像johnathans的回答一样可读,而且写起来更容易一些。尽管如果您添加泛型,您可以强制x为同一类型,并将其用于不同的对象
Item
```int Update(T item, params Expression<Func<T, object>>[] selectors)
{
string getName(Expression e)
{
if(e is LambdaExpression l)
return getName(l.Body);
if(e is MemberExpression m)
return m.Member.Name;
if(e is UnaryExpression u)
return getName( u.Operand);
throw new NotImplementedException();
}
var names = selectors.Select(getName);
}
int Update(T item, params Expression<Func<T, object>>[] selectors)
{
IEnumerable getName(Expression e)
{
if (e is LambdaExpression l)
return getName(l.Body);
if (e is MemberExpression m)
return new[] { m.Member.Name };
if (e is UnaryExpression u)
return getName(u.Operand);
if (e is NewExpression n) // <- to account for the anonymous object
return n.Arguments.SelectMany(getName);
throw new NotImplementedException();
}
var names = selectors.SelectMany(getName);
}
Update(new { foo = "a", bar = 5}, x=>x.foo, x=>x.bar);
Update(new { foo = "a", bar = 5 }, x => new { x.foo, x.bar});