How to do multiple Where validations with Linq and Mongo in c#

Asked

Viewed 43 times

-2

I am developing an Api and in my GET method can be passed word to be searched, start date and end date. However all fields are optional, that is, I can pass only the word without date, I can pass only the dates, I can pass only initial date, I can pass the word with the dates.

What is the best way to make this condition?

I tried it this way:

if (!string.IsNullOrEmpty(statsCommand.SearchString))
    where = c => c.text.Contains(statsCommand.SearchString);

if (statsCommand.StartDate != DateTime.MinValue)
    where = c => c.date == statsCommand.StartDate;

if (statsCommand.StartDate != DateTime.MinValue && statsCommand.EndDate != DateTime.MinValue)
   where = c => c.date >= statsCommand.EndDate && c.date <= statsCommand.StartDate;

Then I do the attribution in the result below:

        result = await collection.AsQueryable()
            .GroupBy(c => c.details.text)
            .Select(d => new Details { text = d.First().details.text, date = d.First().details.date, Searchs = d.Count() })
            .Where(where)
            .OrderByDescending(c => c.Searchs)
            .Skip((statsCommand.PageNumber - 1) * statsCommand.PageSize)
            .Take(statsCommand.PageSize)
            .ToListAsync();

I am not knowing how to make these conditions, is always coming the last true condition and not the junction of them all.

Can anyone help? Thanks in advance

  • You debugged your code and understand what you’re doing?

  • @Leandroangelo pq the question? Of course I understand WHAT I NEED, I do not know how to DO, so I asked here....

1 answer

0


What you described above is resulting in unwanted behavior because you always assign something new to the variable where (from now on let’s call this variable filter as this is the filter for your search). Imagine the field statsCommand.SearchString is neither null nor empty, the variable filter will receive c => c.text.Contains(statsCommand.SearchString), besides the field statsCommand.StartDate is different from DateTime.MinValue, then filter is superscripted to c => c.date == statsCommand.StartDate and this variable can be overwritten once again if the third condition you placed is met. What you need to do to aggregate all these expressions is to use the linqkit which offers a number of extensions to linq, such as the operator .And. First import the package linqkit.core for your project and add it in your class: using LinqKit;. Then do something similar to what follows (as you did not specify your Explanation in the question, imagine a fictitious Explanation IMongoCollection<Foo> collection):

Expression<Func<IGrouping<Foo, Details>, bool>> filter;

if (statsCommand.EndDate == DateTime.MinValue)
    statsCommand.EndDate = DateTime.MaxValue;

filter = c => c.date >= statsCommand.StartDate && c.date <= statsCommand.EndDate;

if (!string.IsNullOrEmpty(statsCommand.SearchString))
    filter = filter.And(c => c.text.Contains(statsCommand.SearchString));

result = await collection.AsQueryable()
    .GroupBy(c => c.details.text)
    .Select(d => new Details { text = d.First().details.text, date = d.First().details.date, Searchs = d.Count() })
    .Where(filter)
    .OrderByDescending(c => c.Searchs)
    .Skip((statsCommand.PageNumber - 1) * statsCommand.PageSize)
    .Take(statsCommand.PageSize)
    .ToListAsync();

Make the necessary adaptations, the above example was just an illustration. The main goal is for you to observe which case statsCommand.SearchString is not null or empty, a new expression will be added to the filter.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.