使用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();
问题是EF IQueryable<T>
上的Concat()
将把整个连接变成一个查询。
当您调用.Concat(sharedViews)
时,您正在传递嵌套实体类的标量(预加载)集合
EF不知道如何将其转换为查询,所以它抱怨道。
您可以通过调用AsEnumerable()
而不是ToList()
来加快速度。
这确实有效。指向能告诉我原因的人!
commonViews.ToList().Concat(ownedViews.ToList()).Concat(sharedViews.ToList()).ToList();
这是因为每个原始查询都是单独执行的;您只是在内存中连接结果。当您组合这3个查询时,实体框架查询转换器中似乎有一个错误,但当您对它们中的每一个调用ToList
时,它们不再是EF查询,它们只是列表,因此使用Linq to Objects将它们连接起来。