【问题标题】:Linq with optional WHERE options带有可选 WHERE 选项的 Linq
【发布时间】:2015-10-04 07:23:17
【问题描述】:

我有一个 .Net 函数,它接受 3 个参数,都是可选的。像这样的:

public List<MyObject> Search(string colour, string size, string name)
{
     var result = (from c in MyTable where .... select c).ToList();     
}

我的问题是,做where 部分的最佳方法是什么。最好是创建动态linq吗?在 linq 中,具有可选 where 参数的最佳模式是什么?

所以,在 SQL 中,是这样的:

SELECT *
FROM MyTable
WHERE (@colour <> '' AND colour = @colour)
  AND (@size <> '' AND size = @size)
  AND (@name <> '' AND name = @name)

但我希望在 linq 中有一个更简洁、更容易接受的模式。

【问题讨论】:

  • 您可以使用Expressions 或一些第 3 部分 Dynamic Linq 库。
  • SQL 执行计划不佳,就像所有包罗万象的查询一样

标签: c# sql linq


【解决方案1】:

在这种情况下,我建议您使用PredicateBuilder 来生成您的查询。您可以从此处复制代码,也可以安装 LinqKit Nuget 包。

使用此代码可让您即时生成动态查询,并防止您编写大量 if/else 语句。

语句如...

p => p.Price > 100 &&
 p.Price < 1000 &&
 (p.Description.Contains ("foo") || p.Description.Contains ("far"))

将由这种代码生成:

var inner = PredicateBuilder.False<Product>();
inner = inner.Or (p => p.Description.Contains ("foo"));
inner = inner.Or (p => p.Description.Contains ("far"));

var outer = PredicateBuilder.True<Product>();
outer = outer.And (p => p.Price > 100);
outer = outer.And (p => p.Price < 1000);
outer = outer.And (inner);

我认为这相当简洁,它也会让你了解表达式的强大功能。

【讨论】:

    【解决方案2】:

    链式Where 子句检查是否为空

    var result = context.MyTable
        .Where(t => color == null || color == t.Color)
        .Where(t => size == null || size == t.Size)
        .Where(t => name == null || name == t.Name)
        .ToList();
    

    另一种方法是仅在需要时添加条件

    var query = context.MyTable;
    
    if (color != null) query = query.Where(t => t.Color == color);
    if (size != null) query = query.Where(t => t.Size == size);
    if (name != null) query = query.Where(t => t.Name == name);
    
    var result = query.ToList();
    

    【讨论】:

    • 像这样的包罗万象的查询会导致错误的执行计划。如果不需要条件,则无需将其添加到链中
    【解决方案3】:
    var results = olstOfObjects.Where(x => 
        (x.size == size || x.size == "") &&
        (x.color == color || x.color == "") &&
        (x.name == name || x.name == "")).ToList();;
    

    【讨论】:

      【解决方案4】:

      您可以在 Search 方法中执行以下操作:

      var query = from c in MyTable select c;
      if (!String.IsNullOrEmpty(colour))
        query = from c in query where c.colour == colour select c;
      if (!String.IsNullOrEmpty(size))
        query = from c in query where c.size == size select c;
      if (!String.IsNullOrEmpty(name))
        query = from c in query where c.name == name select c;
      return query.ToList();
      

      【讨论】:

        【解决方案5】:

        怎么样:

        public List<MyObject> Search(string colour, string size, string name)
        {
            IEnumerable<MyObject> result = MyTable;
        
            if(colour != null)
                result = result.Where(o => o.Colour == colour);
        
            if(size != null)
                result = result.Where(o => o.Size == size);
        
            ...
        
            return result.ToList();
        }
        

        【讨论】:

          【解决方案6】:

          这里有 1 个查询条件:

          public List<object> Search(string colour, string size, string name)
          {
              var query = from c in MyTable
                  where
                      (string.IsNullOrEmpty(colour) || c.colour == colour) &&
                      (string.IsNullOrEmpty(size) || c.size == size) &&
                      (string.IsNullOrEmpty(name) || c.name == name)
                  select c;
          
              return query.ToList();
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-28
            • 1970-01-01
            相关资源
            最近更新 更多