【问题标题】:LINQ is it possible to add where clauses dynamicallyLINQ 是否可以动态添加 where 子句
【发布时间】:2012-12-28 12:10:58
【问题描述】:

我想用不同的键搜索我的数据库。根据输入,可能有 1 个键到 10 个键。有没有办法在我的 Linq 查询中动态添加 OR/AND 子句?

 keys[k] // I have my keys in this array 
 var feedList = (from feed in ctx.Feed
                 where feed.content.contains(keys[0]) 
                       && feed.content.contains(keys[1])
                       && ... // continues with the keys.length
                 select new {
                    FeedId = feed.DuyuruId,
                    FeedTitle = feed.FeedTitle,
                    FeedContent = feed.FeedContents,
                    FeedAuthor = user.UserName + " " +User.UserSurname
 }

【问题讨论】:

  • 我只是补了10个键,应该没有什么限制。
  • @SomeMiscGuy 共享的链接是您所需要的。我已经创建了整个 linq 查询,它就像魅力一样工作。它与现有的 IEnumerableIQueryable 扩展很好地融合在一起。
  • 动态 LINQ 可能是一个有用的解决方案,但在此示例中是不必要的。如果过度使用 LINQ 会产生大量开销,因为它依赖于幕后的反射。

标签: c# linq entity-framework where-clause


【解决方案1】:

你可以使用LINQ的扩展方法

ctx.Feed.Where(f => {  
//Your logic here
if(something != null){
      return f.Property == something
  } 
}).Select( new { FeedId = feed.DuyuruId,
                    FeedTitle = feed.FeedTitle,
                    FeedContent = feed.FeedContents,
                    FeedAuthor = user.UserName + " " +User.UserSurname })

【讨论】:

    【解决方案2】:

    您可以尝试使用.All 子句来检查所有键:

    where keys.All(key => feed.content.contains(key))
    

    【讨论】:

      【解决方案3】:

      你可以做这样的事情。请记住,这可能会导致一些开销

       var students = ctx.Students;
      
       if (!String.IsNullOrWhiteSpace(SearchParams.Name))
            students = from s in students where s.Name.StartsWith(SearchParams.Name)
      
       if (!String.IsNullOrWhiteSpace(SearchParams.Surname))
            students = from s in students where s.Surname.StartsWith(SearchParams.Surname)
      

      【讨论】:

        【解决方案4】:

        对于 AND 子句很简单:

        var feedList = from feed in ctx.Feed;
        foreach(var key in keys){
            feedList = feedList.Where(x=> content.contains(key));
        }
        var resultQuery = feedList.Select(x=> new {....});
        

        对于 OR,您需要使用 Expressions 或尝试 LinqKit 及其谓词:

        var predicate = PredicateBuilder.False<TypeOfYourEntity>();
        foreach(var key in keys){
            predicate = predicate.Or(x=> content.contains(key));
        }
        var resultQuery = ctx.Feed.Where(predicate).Select(x=> new {....});
        

        【讨论】:

          【解决方案5】:

          我想提供一个示例,说明 @mellamokb 的答案如何适用于我的场景,以帮助任何需要相当动态的 linq 查询的人。

          在我的示例中,我只是对 datatable 类进行了扩展,因此我可以检查数据库中是否存在一行数据,因此不会引发 SQL 主键异常。

          /// <summary>
          /// 
          /// </summary>
          /// <param name="DT"></param>
          /// <param name="ColumnNames">Columns to check in affected table.</param>
          /// <param name="ItemtoChecks">Values to check in affected column.</param>
          /// <returns></returns>
          public static bool TableContains(this DataTable DT, string[] ColumnNames, object[] ItemtoChecks)
          {
            var result = from row in DT.AsEnumerable()
                         where ColumnNames.All(
                         r => row.Field<object>(r).ToString() == Convert.ToString(
                           ItemtoChecks[ColumnNames.ToList()
                           .FindIndex(p => p.Equals(r, StringComparison.OrdinalIgnoreCase))]))
                         select row;                   
            return (result.Count() > 0);
          }
          

          此方法允许您向string[] 添加任意数量的列名以及相应的值以签入单独的object[]。查询检查datatable,如果找到匹配项,则方法返回true,否则返回false

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-10-04
            • 1970-01-01
            • 1970-01-01
            • 2020-01-08
            • 2023-03-29
            • 1970-01-01
            • 2010-09-15
            • 2014-12-19
            相关资源
            最近更新 更多