c# - Iterate through the properties of a lambda expression? -
how can iterate through expression , change property names based on custom attribute decorated them with?
i use following code custom attribute of property, works simple expression 1 property:
var comparison = predicate.body binaryexpression; var member = (comparison.left.nodetype == expressiontype.convert ? ((unaryexpression)comparison.left).operand : comparison.left) memberexpression; var value = comparison.right constantexpression; var attribute = attribute.getcustomattribute(member.member, typeof(myattribute)) myattribute; var columnname = attribute.name ?? member.member.name; var columnvalue = value.value;
edit
deriving expressionvisitor
, can change property name overriding method visitmember
.
is place property name used build expression?
you can implement system.linq.expressions.expressionvisitor
rewrite memberexpression
new mapped property. , yes visitmember
place have implement remapping, 1 of advantages expression trees , visitors. weird case have deal if property's type different type of mapped property.
void main() { var data = new list<testclass>(); data.add(new testclass() { firstname = "first", lastname = "last", }); var q = data.asqueryable().select(x => x.firstname); var vistor = new myrewriter(); var newexpression = vistor.visit(q.expression); var output = newexpression.tostring(); //system.collections.generic.list`1[userquery+testclass].select(x => x.lastname) } class testclass { [myattribute(nameof(lastname))] public string firstname { get; set; } public string lastname { get; set; } } class myattribute : attribute { public string mapto { get; } public myattribute(string mapto) { mapto = mapto; } } class myrewriter : expressionvisitor { protected override expression visitmember(system.linq.expressions.memberexpression node) { var att = node.member.getcustomattribute<myattribute>(); if (att != null) { var newmember = node.expression.type.getproperty(att.mapto); if (newmember != null) { return expression.property( visit(node.expression), // important remember visit inner expression newmember); } } return base.visitmember(node); } }
you can run in linqpad test it. code assumes mapping property.
Comments
Post a Comment