0

I have a table with a string/varchar property.

My method accepts a string, which can be a comma separated list.

My goal is to build a dynamic where clause that will loop through the comma separated list and make a where clause with my query but I'm not getting the syntax correct.

public async List<DataObj> GetData(string pets)
{
   IQueryable<DataObj> query = dbSet;
   if (!string.IsNullOrEmpty(pets))
   {
       var split = pets.Split(",");
       foreach (var t in split)
       {
          query = query.Where(x => x.Pets.Contains(t.Trim()));
       }
    }
    return await query.DataObj.AsNoTracking().ToListAsync();
}

So if DataObj.Pets for one record is "dog, cat". And DataObj.Pets for another record is: "dog, birds".

If I put in "birds" as the argument to the repo, it should return DataObj2, if I put in "dog", it should return both, and if I put in "dog, birds" the query should return both DataObj1 and DataObj2.

Is anything wrong with my query, because it's not doing that.

  • _because it's not doing that._ - can you tell what it is doing, did you get some error? – Fabio Oct 08 '21 at 06:06
  • Your requirements are for `Or` condition, by chaining `Where` expressions you are using `And` condition – Fabio Oct 08 '21 at 06:09
  • Chained `.Where()` clauses `AND` in entity framework. Related: [How to chain alternative conditions in where clause in Entity Framework](https://stackoverflow.com/questions/17395417/how-to-chain-alternative-conditions-in-where-clause-in-entity-framework) – mcalex Oct 08 '21 at 06:19
  • Check [this my answer](https://stackoverflow.com/a/67666993/10646316) – Svyatoslav Danyliv Oct 08 '21 at 07:39

1 Answers1

0

If I put in "birds" as the argument to the repo, it should return DataObj2, if I put in "dog", it should return both, and if I put in "dog, birds" the query should return both DataObj1 and DataObj2.

Your requirements are for Or condition, by chaining Where expression you are using And condition

You can use predicate builder or dynamic LINQ to build multiple Or conditions.

Just for fun - you can utilize asynchronous approach

public async Task<List<DataObj>> GetData(string pets)
{
   if (string.IsNullOrEmpty(pets)) return new List<DataObj>();

   var tasks = pets.Split(",")
     .Select(p => context.DataObects.Where(o => o.Pets.Contains(p)).ToListAsync())
     .ToArray();

   await Task.WhenAll(tasks);

   return tasks.SelectMany(t => t.Result).ToList();
}
Fabio
  • 31,528
  • 4
  • 33
  • 72