【问题标题】:Combine some lambda expressions using Or operand使用 Or 操作数组合一些 lambda 表达式
【发布时间】:2011-06-27 05:12:07
【问题描述】:

我想创建一个动态表达式,它将根据未知数量的Or 条件生成:

    IQueryable<Entity> entities = Repository<Entity>.Load();

    Expression<Func<Entity, bool>> wholeFilter;

    foreach(condition in Conditions)
    {           
      Expression<Func<Entity, bool>> filter = e => e.something1 == condition.First && e.something2 == condition.Second
      wholeFilter = wholeFilter.Or(filter)
    }

    return entities.Where(wholeFilter);

我试图实现Or 扩展,但我想不出一个合乎逻辑的方法。

此外,我在PredicateBuilder 周围玩,并写了如下内容:

var predicate = PredicateBuilder.False<Entity>();

以及我循环中的以下代码:

predicate = predicate.Or(filter);

但是我意识到它只是And 条件一起而不是Or 他们......

知道如何生成组合表达式吗?
问候

编辑:
我写的原始代码:

public IQueryable<IEntity> Find(IEntityType entityType, List<AdaptiveObjectModelSpecification> queryObjecs)
{
    if (entityType == null)
        return null;

    var predicate = PredicateBuilder.False<IEntity>();
    var entities = Repository<IEntity>.Find(p => p.EntityType == entityType);

    if (queryObjecs != null)
    {
        foreach (var queryObject in queryObjecs)
        {
            if (entityType.PropertyTypes.Count(p => p.PropertyName == queryObject.PropertyType.PropertyName) == 0)
                throw new MissingFieldException(String.Format("Column {0} not found.", queryObject.PropertyType.PropertyName));

            predicate = predicate.Or(e => e.Properties.Any(p => p.Value == queryObject.SearchValue && p.PropertyType.PropertyName == queryObject.PropertyType.PropertyName));
        }
        entities = entities.Where(predicate);            
    }

    return entities;
}

queryObjects 有两个元素时生成的 entity.Expression.ToString() =

{value(NHibernate.Linq.NhQueryable`1[Azarakhsh.Domain.Core.AdaptiveObjectModel.Interface.IEntity])

.Where(p => (p.EntityType == value(Azarakhsh.Domain.Core.AdaptiveObjectModel.Service.AdaptiveObjectModelRepositoryService+<>c__DisplayClassd).entityType))
// The line below is generated by PredicateBuilder 
.Where(
Param_0 => ((False
OrElse 
Invoke(e => e.Properties.Any(p => ((p.Value == value(Azarakhsh.Domain.Core.AdaptiveObjectModel.Service.AdaptiveObjectModelRepositoryService+<>c__DisplayClass10).queryObject.SearchValue) AndAlso (p.PropertyType.PropertyName == value(Azarakhsh.Domain.Core.AdaptiveObjectModel.Service.AdaptiveObjectModelRepositoryService+<>c__DisplayClass10).queryObject.PropertyType.PropertyName))), Param_0)) 
OrElse 
Invoke(e => e.Properties.Any(p => ((p.Value == value(Azarakhsh.Domain.Core.AdaptiveObjectModel.Service.AdaptiveObjectModelRepositoryService+<>c__DisplayClass10).queryObject.SearchValue) AndAlso (p.PropertyType.PropertyName == value(Azarakhsh.Domain.Core.AdaptiveObjectModel.Service.AdaptiveObjectModelRepositoryService+<>c__DisplayClass10).queryObject.PropertyType.PropertyName))), Param_0)))}

【问题讨论】:

  • 您为什么从不接受答案?
  • 对不起,但我认为实际答案应标记为“已接受”。对吗?
  • 好吧,我在这里遗漏了什么吗?这一切都如我所料......不用说我肯定会投票给与寻找解决方案相关的帖子......

标签: c# linq c#-4.0 expression expression-trees


【解决方案1】:

使用PredicateBuilder.Or当然应该将结果“和”在一起。

您当前在代码的主要 sn-p 中获得的代码将无法编译,因为您使用的是 wholeFilter 而没有为其分配初始值 - 此外,我不知道任何实例或扩展在Expression&lt;TDelegate&gt; 上调用Or 的方法。

我会坚持使用PredicateBuilder,并弄清楚为什么它不起作用 - 因为它当然应该。请使用PredicateBuilder 发布一些代码以及它生成的SQL。

【讨论】:

  • public static Expression> Or(this Expression> left , Expression> right) { LambdaExpression lambdaExpression = RebuildExpressionIfNeeded(left.Parameters[0], right); return Expression.Lambda> (Expression.OrElse(left.Body, lambdaExpression.Body), right.Parameters); }
  • 抱歉迟到了。我很感激你的通知。我编辑了帖子,所以它是原始的。查询的结果是可以满足查询对象的最后一个实体。所以如果有 3 个匹配实体,只会返回最后一个......此外,我不明白为什么 PredicateBuilder.Or "And-" 查询。不应该是他们吗?...
  • @Javid_p84:那个扩展方法是从哪里来的?我仍然不清楚为什么你认为 PredicateBuilder 是“与”表达式,而它显然在生成的表达式中使用 OrElse 。 对 AndAlso 的引用,但那是因为您在表达式中使用了&amp;&amp;
  • @Jon :是的,它显然是在使用 OrElse。但是它不会返回所有匹配的实体,而是最后一个。假设有 10 个匹配的实体,从 1 到 9 的实体不会在返回的列表中。只是 #10 .... 我想它不会保留以前的结果。我在单元测试中遇到了这个问题。所以我对数据很确定......
  • 我可以用联合扩展方法来管理它。但不幸的是它在 NHibernate 3.1 中不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 2016-09-24
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多