繁体   English   中英

IEnumerable 和 IQueryable 可以联合吗?

[英]Can IEnumerable and IQueryable be Union?

我尝试联合 IQueryable 和 IEnumerable 但收到此错误

Union(__p_2)' 无法翻译。 以可翻译的形式重写查询,或通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用显式切换到客户端评估。

并尝试了许多不同的写作方法,但它不起作用。 那么 IEnumerable 和 IQueryable 可以联合吗?

我的数据如下所示:

var users = new List<Person>().AsQueryable();
var user = GetUsersByXXX(XXX, YYY);   // return IQueryable<Person>
var userExtra = GetUsersExtraByXXX(XXX, YYY); // return IEnumerable<Person>

if (userExtra.Any())
{
  users = user.Union(userExtra);
}    

return await users.AsNoTracking().OrderBy(x => x.NAME ).ToListAsync();         

班级

public class Person
{
    public string CODE { get; set; }
    public string NAME { get; set; }
    public string PHONE { get; set; }
}

您必须了解这两件事是两个不同的概念:

  • IQueryable是一个接口, “提供针对特定数据源评估查询的功能”
  • IEnumerable是一个“公开枚举器,支持对集合进行简单迭代”的接口。

通过调用AsEnumerable()可以将IQueryable转换为IEnumerable

请注意, IQueryable可以是非计算表达式。 即尚未从数据库中检索数据。 通过调用ToListAsEnumerable之类的东西,您可以枚举,从而评估它。 正常(同步)方法将阻塞,直到完成。 这就是为什么还有ToListAsyncAsAsyncEnumerable的原因。

IQueryable<T>接口已经实现了IEnumerable<T> ,您只需转换为IEnumerable<T>以确保您使用 linq-to-objects 实现。

var users = GetUsersByXXX(XXX, YYY).AsEnumerable() // "cast" it
    .Union(GetUsersExtraByXXX(XXX, YYY));

添加检查以查看“额外”用户是否为空是不必要的。 如果它已经是空的,则联合本质上将是一个 noop。

错误消息是由您生成的查询无法转换为 SQL 的错误引起的。 似乎IQueryable<T>.Union()无法转换为 SQL 并引发错误。

您需要通过调用错误中提到的方法之一来解决此问题,以强制在 .NET 中执行联合,方法是让实体框架首先检索GetUsersByXXX()的完整数据集,然后在内存中执行联合.

var users = new List<T>().AsQueryable();
var user = GetUsersByXXX(XXX, YYY);   // return IQueryable<T>
var userExtra = GetUsersExtraByXXX(XXX, YYY); // return IEnumerable<T>

if (userExtra.Any())
{
  users = user.AsEnumerable().Union(userExtra);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM