【问题标题】:LINQ to SQL - further modifying IQueryable result set with ContainsLINQ to SQL - 使用 Contains 进一步修改 IQueryable 结果集
【发布时间】:2010-03-05 20:41:34
【问题描述】:

我正在使用 LINQ to SQL,我允许用户通过在 UI 中为 queryStrings 分配值来设置查询。我将主查询设置为返回 IQueryable 结果,然后通过继续对生成的 IQueryable 对象执行操作来优化结果集。一切正常,代码与此类似

var result = (from record in db.Companies
select new Company
{
     Id = record.Id,
     Name = record.Name,
     City = record.City,
     Status = record.Status
});
if (queryName != null && queryName!= "")
{
  result = result.Where(p => p.Name.Contains(queryName));
}

if (queryCity != null && queryCity!= "")
{
   result = result.Where(p => p.City.StartsWith(queryCity));
}

现在我想扩展查询以匹配一组类似于 SQL 中的“IN CLAUSE”的元素。在查询中使用元素列表的位置,例如

string[] queryStatusList = {"x", "y" };

现在我可以像这样编写代码,一切都还可以。

var result = (from record in db.Companies
where queryStatusList.Contains(record.status)
   select new Company
   {
      Id = record.Id,
      Name = record.Name,
      City = record.City,
      Status = record.Status
   });
if (queryName != null && queryName!= "")
{
  result = result.Where(p => p.Name.Contains(queryName));
}

if (queryCity != null && queryCity!= "")
{
   result = result.Where(p => p.City.StartsWith(queryCity));
}

但是,我不想在初始查询中有 where 子句。我想从上一个示例中所做的细化查询结果构建。我的问题是我将如何构建这样的查询。我试过了

if (queryStatusList != null && queryStatusList.Count() > 0)
{
    result = result.Where(queryStatusList.Contains(result.Select(p => p.Status.ToString())));
}

但我得到一个编译器错误:“无法从用法中推断方法 'System.Linq.Enumerable.Contains(System.Collections.Generic.IEnumerable, TSource)' 的类型参数。尝试明确指定类型参数”我尝试了一些变体,但我不确定如何解决这个问题。

【问题讨论】:

    标签: linq-to-sql iqueryable


    【解决方案1】:

    我想如果你稍微改变一下,它可能会起作用:

    if (queryStatusList != null && queryStatusList.Count() > 0) 
    { 
        result = result.Where( r=> queryStatusList.Contains( r.Status )); 
    }
    

    另一方面,您可能希望考虑使用 PredicateBuilder 来构建单个 Where 子句选择器并改用它。 PredicateBuilder 将为您提供更多控制权,并能够使用 AND 和 OR 子句混合创建复杂查询,同时仍然动态构建它们。

    var predicate = PredicateBuilder.True<Company>();
    
    if (queryName != null && queryName!= "") 
    { 
        predicate = predicate.And( p => p.Name.Contains(queryName) );
    } 
    
    if (queryCity != null && queryCity!= "") 
    { 
       predicate = predicate.And(p => p.City.StartsWith(queryCity)); 
    }
    
    if (queryStatusList != null && queryStatusList.Count() > 0) 
    { 
        predicate = predicate.And( p => queryStatusList.Contains( p.Status )); 
    }
    
    var result = db.Companies
                   .Select( c => new Company 
                    { 
                        Id = record.Id, 
                        Name = record.Name, 
                        City = record.City, 
                        Status = record.Status 
                    }
                   .Where( predicate );
    

    【讨论】:

    • 非常感谢。我真的很感激帮助。我花了几个小时试图让它发挥作用。一旦你看到答案,它看起来很容易。再次感谢......
    • 也感谢出色的谓词示例。我从未使用过 PredicateBuilder 类。看起来很不错。
    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多