10

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

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

2 回答 2

5

问题是Concat()在 EF 上IQueryable<T>会将整个串联变成单个查询。

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

您可以通过调用AsEnumerable()而不是ToList().

于 2013-07-18T22:12:30.273 回答
1

这实际上有效。谁能告诉我原因!

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

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

于 2013-07-18T22:12:56.677 回答