Javid_p84
Javid_p84

Reputation: 868

Combine some lambda expressions using Or operand

I want to make a dynamic expression which will be generated out of an unknown number of Or conditions:

    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);

I tried to implement the Or extension but I couldn't come up with a logical way.

Moreover I was playing around the PredicateBuilder and wrote something like:

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

and the code below in my loop:

predicate = predicate.Or(filter);

However I realized that it just And the conditions together not Or them....

Any idea how to generate the combined expression?
regards

EDIT :
the original code that I wrote :

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;
}

generated entities.Expression.ToString() when queryObjects has two elements =

{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)))}

Upvotes: 1

Views: 583

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500015

Using PredicateBuilder.Or should certainly be "and"-ing the results together.

The code you've currently got in the main snippet of code won't compile because you're using wholeFilter without assigning it an initial value - and additionally, I don't know of any instance or extension method called Or on Expression<TDelegate>.

I would stick to PredicateBuilder, and work out why that isn't working - because it certainly should. Please post some code using PredicateBuilder, along with the SQL it generates.

Upvotes: 1

Related Questions