LINQ to SQL Where Clause Optional Criteria

I am working with a LINQ to SQL query and have run into an issue where I have 4 optional fields to filter the data result on. By optional, I mean has the choice to enter a value or not. Specifically, a few text boxes that could have a value or have an empty string and a few drop down lists that could have had a value selected or maybe not…

For example:

    using (TagsModelDataContext db = new TagsModelDataContext())
     {
        var query = from tags in db.TagsHeaders
                    where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
                    && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE
                    && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE
                    select tags;
        this.Results = query.ToADOTable(rec => new object[] { query });
    }

Now I need to add the following fields/filters, but only if they are supplied by the user.

  1. Product Number – Comes from another table that can be joined to TagsHeaders.
  2. PO Number – a field within the TagsHeaders table.
  3. Order Number – Similar to PO #, just different column.
  4. Product Status – If the user selected this from a drop down, need to apply selected value here.

The query I already have is working great, but to complete the function, need to be able to add these 4 other items in the where clause, just don’t know how!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can code your original query:

var query = from tags in db.TagsHeaders
                where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
                && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE
                && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE
                select tags;

And then based on a condition, add additional where constraints.

if(condition)
    query = query.Where(i => i.PONumber == "ABC");

I am not sure how to code this with the query syntax but id does work with a lambda. Also works with query syntax for the initial query and a lambda for the secondary filter.

You can also include an extension method (below) that I coded up a while back to include conditional where statements. (Doesn’t work well with the query syntax):

        var query = db.TagsHeaders
            .Where(tags => tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()))
            .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE)
            .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE)
            .WhereIf(condition1, tags => tags.PONumber == "ABC")
            .WhereIf(condition2, tags => tags.XYZ > 123);

The extension method:

public static IQueryable<TSource> WhereIf<TSource>(
    this IQueryable<TSource> source, bool condition,
    Expression<Func<TSource, bool>> predicate)
{
    if (condition)
        return source.Where(predicate);
    else
        return source;
}

Here is the same extension method for IEnumerables:

public static IEnumerable<TSource> WhereIf<TSource>(
    this IEnumerable<TSource> source, bool condition,
    Func<TSource, bool> predicate)
{
    if (condition)
        return source.Where(predicate);
    else
        return source;
}

Method 2

Just need to use a conditional checking for the parameter’s existence. For instance:

where (string.IsNullOrEmpty(ProductNumber) || ProductNumber == tags.productNumber)

That way if the product number isn’t entered that expression will return true in all cases, but if it is entered it will only return true when matching.

Method 3

You have the ability to OR with ||.

Check out this thread, as it might give you some nice pointers:
C# LINQ equivalent of a somewhat complex SQL query


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x