Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ query AND & OR

Tags:

c#

.net

sql

linq

I'm starting my journey with .NET and I need a little help.

I will describe my situation by example what I have and what I need to do but I don't know how to do that.

So I have a class like this

public class Ban
{
    public int ID { get; set; }
    public string Nick { get; set; }
    public string IP { get; set; }
    public string GroupName { get; set; }
}

and variable bans which is IQueryable

Then in method of signature

public IEnumerable<Ban> FindBans(Ban filter);

I need to search through that bans variable;

How I search now

public IEnumerable<Ban> FindBans(Ban filter)
{
    var bans = GetBansQueryable();

    if (!string.IsNullOrWhiteSpace(filter.GroupName))
    {
        bans = bans.Where(b => b.GroupName == filter.GroupName);
    }
    if (!string.IsNullOrWhiteSpace(filter.Nick))
    {
        bans = bans.Where(b => b.Nick == filter.Nick);
    }
    if (!string.IsNullOrWhiteSpace(filter.IP))
    {
        bans = bans.Where(b => b.IP == filter.IP);
    }

    return bans.AsEnumerable();
}

Which filters with AND. SQL query part will be like this

... WHERE group_name = 'abc' AND nick = 'def' AND ip = 'ghi';

What I need is

... WHERE group_name = 'abc' AND (nick = 'def' OR ip = 'ghi');

All of this need to be dynamic (if we don't pass GroupName don't filter by it etc.) I have no idea how I can achieve that beside making this dynamics manualy like

if (!string.IsNullOrWhiteSpace(filter.GroupName) && 
    string.IsNullOrWhiteSpace(filter.Nick) && 
    string.IsNullOrWhiteSpace(filter.IP))
{
    bans = bans.Where(b => b.GroupName == filter.GroupName);
}
else if (!string.IsNullOrWhiteSpace(filter.GroupName) && 
    !string.IsNullOrWhiteSpace(filter.Nick) && 
    string.IsNullOrWhiteSpace(filter.IP))
{
    bans = bans.Where(b => b.GroupName == filter.GroupName && b.Nick == filter.Nick);
}
else if (!string.IsNullOrWhiteSpace(filter.GroupName) && 
    !string.IsNullOrWhiteSpace(filter.Nick) && 
    !string.IsNullOrWhiteSpace(filter.IP))
{
    bans = bans.Where(b => b.GroupName == filter.GroupName && (b.Nick == filter.Nick || b.IP == filter.IP));
}

and so on... and now add another variable to Ban.

like image 337
David Skuza Avatar asked Dec 18 '25 19:12

David Skuza


2 Answers

I think you can simplify you entire constraint like this:

bans = bans.Where(b => ( string.IsNullOrWhiteSpace(filter.GroupName) || b.GroupName == filter.GroupName )
                        &&
                        ( ( string.IsNullOrWhiteSpace(filter.Nick) || b.Nick == filter.Nick )
                          ||
                          ( string.IsNullOrWhiteSpace(filter.IP) || b.IP == filter.IP )
                        )
                 );
like image 71
Patrick Hofman Avatar answered Dec 21 '25 10:12

Patrick Hofman


You probably would like to look at Scott Hansleman blog post on dynamic sql, predicate builder and linqkit:

The Weekly Source Code 48 - DynamicQueryable makes custom LINQ expressions easier

Otherwise there is a very nice blog post about using dynamic filter with Kendo UI grid and Web Api:

Kendo UI Open Sources Dynamic LINQ Helpers

like image 37
Dr Alex Avatar answered Dec 21 '25 12:12

Dr Alex