Creating a common predicate function

前端 未结 5 1296
南方客
南方客 2020-12-14 01:17

Firstly, I am not sure what terms to use to ask this question, which is probably why I have not found an answer from searching myself.

So I am working with Linq to S

相关标签:
5条回答
  • 2020-12-14 01:31

    I think this will work, and I think I've used it in my Linq-to-SQL project, but I can't find an example offhand. If it doesn't, let me know.


    Rather than creating a function, create a new property on the Users object:

    partial class Users {
       bool CheckForFlags
        {
           get { 
              return Flag1 || Flag2 || Flag3 || Flag4 || Flag5;
           }
        }
    }
    

    Then you should be able to do

    var users = DataContext.Users.Where(x => x.CheckForFlags);
    
    0 讨论(0)
  • 2020-12-14 01:34

    Have you tried PredicateBuilder? I haven't used it in over a year, but I found it effective when writing "Or Where" Queries.

    http://www.albahari.com/nutshell/predicatebuilder.aspx

    An example from their page:

    IQueryable<Product> SearchProducts (params string[] keywords)
    {
      var predicate = PredicateBuilder.False<Product>();
    
      foreach (string keyword in keywords)
      {
        string temp = keyword;
        predicate = predicate.Or (p => p.Description.Contains (temp));
      }
      return dataContext.Products.Where (predicate);
    }
    
    0 讨论(0)
  • 2020-12-14 01:51

    The neat thing about how LINQ to SQL handles expressions is that you can actually build out expressions elsewhere in your code and reference them in your queries. Why don't you try something like this:

    public static class Predicates
    {
        public static Expression<Func<User, bool>> CheckForFlags()
        {
            return (user => user.Flag1 || user.Flag2 || user.Flag3 ||
                            user.Flag4 || user.Flag5);
        }
    
        public static Expression<Func<User, bool>> CheckForCriteria(string value)
        {
            return (user => user.Criteria1 == value);
        }
    }
    

    Once you have your predicates defined, it's very easy to use them in a query.

    var users = DataContext.Users
        .Where(Predicates.CheckForFlags())
        .Where(Predicates.CheckForCriteria("something"));
    
    0 讨论(0)
  • 2020-12-14 01:54

    Like you said, this is a restriction because you are using Linq to SQL.

    Something like this should work though:

    var users = DataContext.Users.Where(x => x.Criteria1 == "something")
                                 .ToArray()
                                 .Where(x => CheckForFlags(x));
    
    0 讨论(0)
  • 2020-12-14 01:58

    To the best of my knowledge there are two possible ways to do this.

    The quick-n-easy way to is filter your results after the SQL executes, with something like this:

    var users = DataContext.Users.Where(x => x.Criteria1 == "something");
        .ToEnumerable()
        .Where(x => CheckForFlags(x));
    

    However this is very poor in terms of performance. It will return ALL rows from the database matching only the first criteria, and then filter the results in memory on the client. Functional, but far from optimal.

    The second, much more performant option is to create a UDF on the database itself and call it from LINQ. See for example this question. The obvious downside is that it moves code into the database, which no one likes to do (for lots of valid reasons).

    There may very well be other viable solutions, but those are the only two I know of.

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