将表达式的一部分定义为c#中的变量
我有以下代码:
public class MyClass { Expression<Func> Criteria {get; set;} } public class Customer { //.. public string Name {get; set;} }
并使用如下:
var c = new MyClass(); c.Criteria = x.Name.StartWith("SomeTexts");
有没有办法定义这样的东西:
? p = x=>x.Customer.Name; var c = new MyClass(); c.Criteria = p => p.StartWith("SomeTexts");
我使用Expression<Func>
将它用作我的linq to entities
查询中的where子句(EF代码优先)。
您可以使用以下帮助程序函数(可以为它们提供更好的名称,但这不是必需的):
public static class ExpressionUtils { public static Expression> Bind(this Expression> source, Expression> resultSelector) { var body = new ParameterExpressionReplacer { source = resultSelector.Parameters[0], target = source.Body }.Visit(resultSelector.Body); var lambda = Expression.Lambda>(body, source.Parameters); return lambda; } public static Expression> ApplyTo(this Expression> source, Expression> innerSelector) { return innerSelector.Bind(source); } class ParameterExpressionReplacer : ExpressionVisitor { public ParameterExpression source; public Expression target; protected override Expression VisitParameter(ParameterExpression node) { return node == source ? target : base.VisitParameter(node); } } }
让我们看一下样本表达式
c.Criteria = x => x.Name.StartsWith("SomeTexts");
可以从两个不同的部分构建。
如果你有
Expression> e = x => x.Name;
然后
c.Criteria = e.Bind(x => x.StartsWith("SomeTexts"));
或者如果你有这个
Expression> e = x => x.StartsWith("SomeTexts");
然后
c.Criteria = e.ApplyTo((Customer x) => x.Name);
如果你有两个表达式,那么你可以使用这两个函数中的任何一个,因为a.Bind(b)
相当于b.ApplyTo(a)
。
您必须定义类型变量explicit,但下一代码将帮助您解决您的场景:
// define new expression that get an Order object and returns string value Expression> p = x => x.Customer.Name; var c = new MyClass(); // Compile the expression to the Func then invoke it and call extra criteria c.Criteria = o => p.Compile().Invoke(o).StartsWith("SomeText");
没有表达式,有一点简单的解决方案:
Func p = x => x.Customer.Name; var c = new MyClass(); c.Criteria = o => p(o).StartsWith("SomeText");
您还可以在MyClass
使用Func<>
而不是Expression<>
:
public MyClass { Func Criteria {get; set;} }
我没有看到在这里使用Expression
的好处。 一个直的Func
怎么样?
public class MyClass { public Func Criteria { get; set; } }
然后…
var myCustomer = new MyClass { Criteria = (c, s) => c.Name.StartsWith(s) }; var customer = new Customer { Name = "Bob" }; var x = myCustomer.Criteria(customer, "B");
如果需要表达式,则可以使用LinqKit执行以下操作:
Expression> p = x => x.Name; var c = new MyClass(); c.Criteria = x => p.Invoke(x).StartsWith("asd"); //Reuse p expression c.Criteria = c.Criteria.Expand();
Invoke
是LinqKit提供的一种扩展方法,可以帮助您轻松地编写表达式。
在调用Expand
方法之后, c.Criteria
将包含一个与完成此操作完全相同的表达式:
上述就是C#学习教程:将表达式的一部分定义为c#中的变量分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
c.Criteria = x => x.Name.StartsWith("asd");
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1009866.html