使用LINQ将三个列表连接为一个列表会引发异常

本文关键字:列表 一个 异常 LINQ 三个 使用 连接 | 更新日期: 2023-09-27 18:23:47

好吧,我一定在做一些愚蠢的事情,但这不应该起作用吗?我有以下三个列表:

var commonViews = (from v in context.TPM_VIEWS where v.VIEWID < 0 select v); // IQueryable<TPM_VIEWS>
var ownedViews = (from v in context.TPM_VIEWS where v.OWNERID == userId && v.VIEWID > 0 select v); // IQueryable<TPM_VIEWS>
var sharedViews = (from v in context.TPM_USER.Include("TPM_VIEWS2") where v.USERID == userId select v).First().TPM_VIEWS2; // EntityCollection<TPM_VIEWS>

每个列表都有适当的值和计数。我可以返回以下列表中的任何一个:

return commonViews.ToList();

我可以返回以下列表中的任意一个两个

return commonViews.Concat(ownedViews).ToList();

然而,当我试图返回所有三个:

return commonViews.Concat(ownedViews).Concat(sharedViews).ToList();

我得到了一个例外:

无法创建"Entity.TPM_VIEWS"类型的常数值。仅在此上下文中支持基元类型或枚举类型。

我做错了什么?这三个值确实都是可枚举的。大多数情况下,我之所以问这个问题,是因为这是保证我会在发布后30秒注意到问题的最佳方式。

更新:

我有93%的把握问题就在这里:

var sharedViews = (from v in context.TPM_USER.Include("TPM_VIEWS2") where v.USERID == userId select v).First().TPM_VIEWS2;

这个看起来像是TPM_VIEWS对象的可枚举列表,我可以在它上面调用ToList()并获得正确的数据,但它与其他列表不兼容。

更新2:

这确实有效。指向能告诉我原因的人!

commonViews.ToList().Concat(ownedViews.ToList()).Concat(sharedViews.ToList()).ToList();

使用LINQ将三个列表连接为一个列表会引发异常

问题是EF IQueryable<T>上的Concat()将把整个连接变成一个查询。

当您调用.Concat(sharedViews)时,您正在传递嵌套实体类的标量(预加载)集合
EF不知道如何将其转换为查询,所以它抱怨道。

您可以通过调用AsEnumerable()而不是ToList()来加快速度。

这确实有效。指向能告诉我原因的人!

commonViews.ToList().Concat(ownedViews.ToList()).Concat(sharedViews.ToList()).ToList();

这是因为每个原始查询都是单独执行的;您只是在内存中连接结果。当您组合这3个查询时,实体框架查询转换器中似乎有一个错误,但当您对它们中的每一个调用ToList时,它们不再是EF查询,它们只是列表,因此使用Linq to Objects将它们连接起来。