嗨,谢谢你抽出时间回答我的问题。
在使用Java一年半之后,我决定切换回.NET。我必须说在VS2012中我有宾至如归的感觉。
在使用Java时,我遇到了一个hibernate实现,它可以轻松创建动态查询。
想象一下,我有一个包含5个字段的表单,其中只有一个字段必须填充,以便我按照过滤结果。
有没有办法在C#中执行以下操作:
if(txtMunicipality.text.length > 0){
(x => x.municipality == txtMunicipality.text)
}
if(chkboxIsFinished){
(x => x.isfinished == true)
}
等。
所以我ccheck每个字段,如果已填充该值,则将该条件添加到查询中...在完成检查后,我执行查询。有没有办法在C#中做到这一点?
答案 0 :(得分:2)
最简单的方法是编写两个查询,即
IQueryable<Foo> query = ... // or possibly IEnumerable<Foo>
if(!string.IsNullOrEmpty(txtMunicipality.text)) {
query = query.Where(x => x.municipality == txtMunicipality.text);
}
if(chkboxIsFinished) {
query = query.Where(x.isfinished);
}
你可以也直接组成表达式树和委托;如果您需要,请说明您拥有的内容:表达式树与委托人。
编辑:这是你如何编写表达式而不是查询:
static class Program
{
static void Main()
{
Expression<Func<int, bool>> exp1 = x => x > 4;
Expression<Func<int, bool>> exp2 = x => x < 10;
Expression<Func<int, bool>> exp3 = x => x == 36;
var combined = (exp1.AndAlso(exp2)).OrElse(exp3);
// ^^^ equiv to x => (x > 4 && x < 10) || x == 36
}
static Expression<Func<T, bool>> OrElse<T>(this Expression<Func<T, bool>> x, Expression<Func<T, bool>> y)
{ // trivial cases
if (x == null) return y;
if (y == null) return x;
// rewrite using the parameter from x throughout
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
x.Body,
SwapVisitor.Replace(y.Body, y.Parameters[0], x.Parameters[0])
), x.Parameters);
}
static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> x, Expression<Func<T, bool>> y)
{ // trivial cases
if (x == null) return y;
if (y == null) return x;
// rewrite using the parameter from x throughout
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
x.Body,
SwapVisitor.Replace(y.Body, y.Parameters[0], x.Parameters[0])
), x.Parameters);
}
class SwapVisitor : ExpressionVisitor
{
public static Expression Replace(Expression body, Expression from, Expression to)
{
return new SwapVisitor(from, to).Visit(body);
}
private readonly Expression from, to;
private SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
}
答案 1 :(得分:1)
是的,有可能。最简单的方法是 delegates ,尤其是匿名的。
例如:
Func<YourEntity, bool> filter = (_ => true); // Default value.
if (txtMunicipality.text.length > 0)
{
filter = (x => x.municipality == txtMunicipality.text);
}
else if (chkboxIsFinished)
{
filter = (x => x.isfinished == true);
}
然后你可以在查询中使用filter
委托,例如在Where
声明中(我认为这是你的意图 - 如果没有,该示例仍然相关,只是不直接适用)
/ LINQ syntax.
var entities = from e in context
where filter(e)
select e;
// Method syntax.
var entities = context.Where(x => filter(x));
// Or simply:
var entities = context.Where(filter);
答案 2 :(得分:1)
在本文中,您可以找到一些有用的扩展方法,它们允许您组合谓词(它也适用于NHibernate):
LINQ to Entities: Combining Predicates
然后你可以构建一个这样的lambda表达式:
Expression<Func<MyObject, bool>> predicate = x => true;
if(txtMunicipality.text.length > 0){
predicate = predicate.And(x => x.municipality == txtMunicipality.text);
}
if(chkboxIsFinished){
predicate = predicate.And(x => x.isfinished == true);
}