LINQ: adding where clause only when a value is not null

后端 未结 10 840
花落未央
花落未央 2020-12-15 17:38

I know a typical way is like this:

IQueryable query = from staff in dataContext.Staffs;
if(name1 != null)
{
     query = from staff in query where (staff.nam         


        
相关标签:
10条回答
  • 2020-12-15 18:01

    The best way to do this is to create yourself an extension method that will take in a conditional statement and a where expression. If the condition is true then it will use the where expression else it will not use it. This can dramatically clean up your code, eliminating the need for if statements.

    public static class LinqExtensions
    {
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> whereClause)
        {
            if (condition)
            {
                return query.Where(whereClause);
            }
            return query;
        }
    }
    

    Now you can write your code like this:

    IQueryable<Staffs> query = dataContext.Staffs.AsQueryable().WhereIf(name1 != null, x => x.Name == name1);
    
    0 讨论(0)
  • 2020-12-15 18:01

    I've seen this pattern in standard SQL, and it seems useful if you have several parameters that may be NULL. For example:

    SELECT * FROM People WHERE ( @FirstName IS NULL OR FirstName = @FirstName )
                           AND ( @LastName IS NULL OR LastName = @LastName )
    

    If you see this in LINQ, it's possible they just blindly translated their old SQL-queries.

    0 讨论(0)
  • 2020-12-15 18:01

    For EF Core I broke it up like this:

    IQueryable<Partners> recs = contextApi.Partners;
    if (status != -1)
    {
       recs = recs.Where(i => i.Status == status);
    }
    recs = recs.OrderBy(i => i.Status).ThenBy(i => i.CompanyName);
    foreach (var rec in recs)
    {
    }
    

    I had to be explicit with my typing instead of relying on var.

    0 讨论(0)
  • 2020-12-15 18:03

    LINQ is diffrent in some other causes (not in this causes), LINQ is the way to get data in the "Faster way" with a littel code and clear cod as possible, there a many benefits of LINQ:

    1. Makes it easier to transform data into objects. I'm sure you've heard the term "Impedence Mismatch" being used quite often, meaning that LINQ reduces the amount of work you must do to translate between object-oriented code and data paradigms such as hierarchical, flat-file, messages, relational, and more. It doesn't eliminate the "Impedence Mismatch" because you must still reason about your data in its native form, but the bridge from here to there is (IMO) much shorter.

    2. A common syntax for all data. Once you learn query syntax, you can use it with any LINQ provider. I think this is a much better development paradigm than the Tower of Babel that has grown over the years with data access technologies. Of course, each LINQ provider has unique nuances that are necessary, but the basic approach and query syntax is the same.

    3. Strongly typed code. The C# (or VB.NET) query syntax is part of the language and you code with C# types, which are translated into something a provider understands. This means that you gain the productivity of having your compiler find errors earlier in the development lifecycle than elsewhere. Granted, many errors in stored proc syntax will generate errors when you save, but LINQ is more general than SQL Server. You have to think of all the other types of data sources that generate runtime errors because their queries are formed with strings or some other loosely typed mechanism.

    4. Provider integration. Pulling together data sources is very easy. For example, you can use LINQ to Objects, LINQ to SQL, and LINQ to XML together for some very sophisticated scenarios. I think it's very elegant.

    5. Reduction in work. Before LINQ, I spent a lot of time building DALs, but now my DataContext is the DAL. I've used OPFs too, but now I have LINQ that ships with multiple providers in the box and many other 3rd party providers, giving me the benefits from my previous points. I can set up a LINQ to SQL DataContext in a minute (as fast as my computer and IDE can keep up).

    6. Performance in the general case doesn't become an issue. SQL Server optimizes queries quite well these days, just like stored procs. Of course, there are still cases where stored procs are necessary for performance reasons. For example, I've found it smarter to use a stored proc when I had multiple interactions between tables with additional logic inside of a transaction. The communications overhead of trying to do the same task in code, in addition to getting the DTC involved in a distributed transaction made the choice for a stored proc more compelling. However, for a query that executes in a single statement, LINQ is my preferred choice because even if there was a small performance gain from a stored proc, the benefits in previous points (IMO) carry more weight.

    7. Built-in security. One reason I preferred stored procs before LINQ was that they forced the use of parameters, helping to reduce SQL injection attacks. LINQ to SQL already parameterizes input, which is just as secure.

    8. LINQ is declarative. A lot of attention is paid to working with LINQ to XML or LINQ to SQL, but LINQ to Objects is incredibly powerful. A typical example of LINQ to Objects is reading items from a string[]. However, that's just a small example. If you think about all of the IEnumerable collections (you can also query IEnumerable) that you work with every day, the opportunities are plentiful. i.e. Searching an ASP.NET ListBox control for selected items, performing set operations (such as Union) on two collections, or iterating through a List and running a lambda in a ForEach of each item. Once you begin to think in LINQ, which is declarative in nature, you can find many of your tasks to be simpler and more intuitive than the imperative techniques you use today.

    I could probably go on, but I'd better stop there. Hopefully, this will provide a more positive view of how you could be more productive with LINQ and perhaps see it as a useful technology from a broader perspective.

    0 讨论(0)
  • 2020-12-15 18:03

    So I tried the .Where(..., x => ...) extension method listed here as an answer but it doesn't work against Entity Framework as Linq To Entities doesn't know how to translate that into TSQL.

    So here's my solution getting my Func on:

    Expression<Func<SomeEfPoco, bool>> columnBeingFilteredPredicate = x => true; // Default expression to just say yes
    if (!string.IsNullOrWhiteSpace(someColumnBeingFilteredValue))
    {
        columnBeingFilteredPredicate = x => x.someColumnBeingFiltered == someColumnBeingFilteredValue;
    }
    
    _context.SomeEfPocos.Where(x => ..... &&
                ..... &&
                ..... &&)
    .Where(columnBeingFilteredPredicate);
    

    someColumnBeingFilteredValue in my case is a string parameter on the encapsulating method with a default value of NULL.

    0 讨论(0)
  • 2020-12-15 18:08

    No, I am not strongly agree with you. here you just gave a simple logic

    if(name1 != null)
    // do your stuff
    

    but what will happen if you do something different with the name1 that have null value..!! Ok, now consider this situation. In this example you shows how to handle possible null values in source collections. An object collection such as an IEnumerable<T> can contain elements whose value is null. If a source collection is null or contains an element whose value is null, and your query does not handle null values, a NullReferenceException will be thrown when you execute the query.

    Probably this could be a issue...

    0 讨论(0)
提交回复
热议问题