2

I have a LINQ query (which will be executed against a DbContext), which I start off by building using some conditions I know of beforehand.

var r = from p in db.People
        where blah
        select p;

I then have a bunch of search conditions, provided as an array (string[]). If I wanted to do an AND, this is easy:

foreach (string s in searchParameters)
{
      r = from r1 in r
          where r1.field == s
          select r1;
}

However, I now have a need to use these parameters in an OR fashion. One solution is to do something like:

var results = new List<IEnumerable<RowType>>();
foreach (string s in searchParameters)
{
      var r2 = from r1 in r
          where r1.field == s
          select r1;
      results.Add(r2);
}

and then, at the end, do a UNION of all the entries in "results". But, this would translate to a much more needlessly complicated query on the DB, and also introduce potentially duplicate rows which I'd then need to de-dup.

Is there an easy as well as efficient way to achieve what I'm trying to do?

Thanks

md1000
  • 149
  • 8

2 Answers2

2

you need to make use of PredicateBuilder, If i am getting correctly you are making single query and you need conditions in it

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}

Dynamically Composing Expression Predicates

Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
0

You could use the System.Linq.Dynamic package available on Nuget. You can also follow this guide on how to use the package.

In your case, I believe the query could be:

var query = IQueryable<DataType>();
foreach(string parameter in searchParameters)
{
   query = query.Where("fieldName ==" + parameter );
}

// call the LINQ query at the end when all the conditions are built
var results = query.Select(q => q.field).ToList();

This may work for your case, otherwise you could use a predicate builder as per Pranay's suggestion.

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291