【问题标题】:Conditional where with or criteria linqtosql有条件的 where 或条件 linqtosql
【发布时间】:2009-12-17 10:48:20
【问题描述】:

我已经弄清楚了如何使用 linq to sql 进行条件查询,并且我还弄清楚了如何 OR where 子句。不幸的是,我无法弄清楚如何同时做到这两个。我可以做一个条件 where 子句,例如:

var ResultsFromProfiles = from AllPeeps in SearchDC.aspnet_Users
                          select AllPeeps;


if (SearchFirstNameBox.Checked)
{
    ResultsFromProfiles = ResultsFromProfiles.Where(p => p.tblUserProfile.FirstName.Contains(SearchTerm));
}

if (SearchLastNameBox.Checked)
{
    ResultsFromProfiles = ResultsFromProfiles.Where(p => p.tblUserProfile.LastName.Contains(SearchTerm));
}

这将为我提供名字和姓氏包含搜索词的任何个人资料。

或者我可以这样做:

var ResultsFromProfiles = from p in SearchDC.aspnet_Users
                          where p.tblUserProfile.LastName.Contains(SearchTerm) ||
                                p.tblUserProfile.FirstName.Contains(SearchTerm)
                          select p;

这将为我提供名字或姓氏包含搜索词的任何个人资料。

我有一堆复选框,用户可以在其中指定他们想要搜索哪些字段来搜索搜索词,所以我希望能够构建一个查询,有条件地添加它们,就像上面的第一个代码 sn-p 一样,但是将它们添加为 OR,以便它们像第二个 sn-p 一样工作。这样,它将在指定字段中的任何位置搜索任何匹配项。

有什么建议吗?

【问题讨论】:

    标签: c# asp.net linq linq-to-sql


    【解决方案1】:

    是的,使用PredicateBuilder。它允许您使用 And 或 Or 语义构建动态查询。它免费且稳定 - 我到处都在使用它。

    【讨论】:

    • 天哪,我不知道那个谓词生成器
    • 哦,看起来不错。特别是与替代建议相比(请参阅下面的我的条目)
    • 太棒了,这正是我所需要的,而且非常简单/优雅。谢谢
    【解决方案2】:

    一种方法是为您的查询操作 LINQ 表达式树。在您的情况下,您需要构建一个 lambda 表达式并将其替换为您对 Where 的调用。这是一个基于列表的工作示例,但无论查询提供程序如何,操作表达式树的代码都是相同的。

    List<User> Users = new List<User>();
    Users.Add(new User() { FirstName = "John", LastName = "Smith" });
    Users.Add(new User() { FirstName = "Jane", LastName = "Smith" });
    
    
    string Query = "John";
    
    var Queryable = Users.AsQueryable();
    
    var Results = (from u in Queryable
                   select u);
    
    //initial method call... the lambda u => false is a place-holder that is about to be replaced
    MethodCallExpression WhereExpression = (MethodCallExpression)Results.Where(u => false).Expression;
    
    //define search options
    Expression<Func<User, string, bool>> FilterLastName = (u, query) => u.LastName.Contains(query);
    Expression<Func<User, string, bool>> FilterFirstName = (u, query) => u.FirstName.Contains(query);
    
    //build a lambda based on selected search options... tie the u parameter to UserParameter and the query parameter to our Query constant
    ParameterExpression UserParameter = Expression.Parameter(typeof(User), "u");
    Expression Predicate = Expression.Constant(false);  //for simplicity, since we're or-ing, we'll start off with false || ...
    
    //if (condition for filtering by last name)
    {
        Predicate = Expression.Or(Predicate, Expression.Invoke(FilterLastName, UserParameter, Expression.Constant(Query)));
    }
    
    //if (condition for filtering by first name)
    {
        Predicate = Expression.Or(Predicate, Expression.Invoke(FilterFirstName, UserParameter, Expression.Constant(Query)));
    }
    
    //final method call... lambda u => false is the second parameter, and is replaced with a new lambda based on the predicate we just constructed
    WhereExpression = Expression.Call(WhereExpression.Object, WhereExpression.Method, WhereExpression.Arguments[0], Expression.Lambda(Predicate, UserParameter));
    
    //get a new IQueryable for our new expression
    Results = Results.Provider.CreateQuery<User>(WhereExpression);
    
    //enumerate results as usual
    foreach (User u in Results)
    {
        Console.WriteLine("{0} {1}", u.FirstName, u.LastName);
    }
    

    Working with expression trees 通常可以使用访问者模式来简化,但我省略了这一点,以便您可以更清楚地看到必须完成的工作。

    【讨论】:

      【解决方案3】:

      这是一个建议。

      我没试过编译运行,LinqToSQL充满惊喜,所以不保证:-)

      var ResultsFromProfiles = from AllPeeps in SearchDC.aspnet_Users select AllPeeps;
      
      IEnumerable<AspNet_User> total = new AspNew_User[0];
      
      if (SearchFirstNameBox.Checked)
      {    
          total = total.Concat(ResultsFromProfiles.Where(p => p.tblUserProfile.FirstName.Contains(SearchTerm));}
      }
      
      if (SearchLastNameBox.Checked)
      {
         total = total.Concat(ResultsFromProfiles.Where(p => p.tblUserProfile.LastName.Contains(SearchTerm));
      }
      
      total = total.Distinct();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-11
        • 2017-03-25
        • 2010-11-26
        相关资源
        最近更新 更多