Maxim
Maxim

Reputation: 4214

Execute LINQ with or without where clause

In my example i want to get promotion elements for a promo code name that is provided if name is not provided then take all available promotions.

var result = from row in promoCodes.AsEnumerable() 
             where  (
                 !String.IsNullOrEmpty(fieldTitle) && 
                 !String.IsNullOrEmpty(filterValue) && 
                 row[fieldTitle].Equals(filterValue)
             ) || true
             select new PromoCodeInfoContainer
             {
                 BannerLink = row["BannerLink"] as string
                 ....
             };

I tried to follow SQL technique where if no conditions provided then OR will be whatever that doesn't impact selection (|| true). In linq this didn't work, it always returns all entries regardless of "fieldTitle" and "filterValue" are not empty. Can anybody suggest a right way to do it?

Upvotes: 0

Views: 3176

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236218

var result = from row in promoCodes.AsEnumerable() 
             where  String.IsNullOrEmpty(fieldTitle) ||                  
                    String.IsNullOrEmpty(filterValue) ||
                    row[fieldTitle].Equals(filterValue)  
             select new PromoCodeInfoContainer
             {
                 BannerLink = row["BannerLink"] as string
             };

If either fieldTitle of filterValue is null or empty, then row filtering will not be executed.

Another option (I think fluent interface looks better here):

var query = promoCodes.AsEnumerable();

if (!String.IsNullOrEmpty(fieldTitle) && !String.IsNullOrEmpty(fieldValue))
    query = query.Where(row => row[fieldTitle].Equals(filterValue));

var result = query.Select(row => new PromoCodeInfoContainer { ... });

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1062780

Firstly, remove the || true - that will return every row, always - hence the problem.

One nice way to do this would be composition - this then avoids the need to test the fieldTitle / fieldValue for every row when they have values, or do anything much at all per-row if they are blank:

var query = promoCodes.AsEnumerable();
if(!string.IsNullOrEmpty(fieldTitle) && !string.IsNullOrEmpty(fieldValue))
{
    query = from row in query
            where filterValue.Equals(row[fieldTitle])
            select row;
}
var result = from row in query
             select new PromoCodeInfoContainer {...}

Note I also reversed the Equals so that the thing-we-know-isn't-null is on the left; although depending on the data-types, Equals(x,y) or x == y may be preferable.

Upvotes: 2

Related Questions