LINQ to SQL - 使用 Contains 进一步修改 IQueryable 结果集

发布于 2024-08-23 19:45:17 字数 1632 浏览 4 评论 0原文

我正在使用 LINQ to SQL,并且允许用户通过向 UI 中的 queryString 分配值来设置查询。我设置主查询以返回 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)' 的类型参数。尝试显式指定类型参数”我尝试了一些变体,但我不确定如何解决该问题。

I am using LINQ to SQL and I am allowing users to set up the query via assigning values to queryStrings in the UI. I set up the primary query to return an IQueryable result and then keep refining the results set by continuing to act upon the resulting IQueryable object. Everything works fine and the code looks similar to this

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));
}

Now I want to extend the query my getting matching a set of elements similar to “IN CLAUSE” in SQL. Where there is a list of elements to use in the query e.g.

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

And now I can write the code like this and everything is still OK.

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));
}

But, I don’t want to have a where clause in the initial query. I want to build from the refined query result as done in the previous example. My question is how would I structure such a query. I tried

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

But I get a compiler error: “The type arguments for method 'System.Linq.Enumerable.Contains(System.Collections.Generic.IEnumerable, TSource)' cannot be inferred from the usage. Try specifying the type arguments explicitly” I have tried a few variations but I’m not sure how to fix the issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若能看破又如何 2024-08-30 19:45:17

我认为如果你稍微改变它,它可能会起作用:

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 );

I think if you change it slightly, it may work:

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

On the other hand, you might want to look at using a PredicateBuilder to build up a single Where clause selector and use it instead. The PredicateBuilder will give you more control and the ability to create complex queries with a mix of AND and OR clauses while still building them up dynamically.

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 );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文