我的数据库上下文中有一个如下所示的方法:
public override async Task<IEnumerable<FeedMessage>> GetLatestFeeds(
int userId,
int groupId,
int maxResults = 15,
long lastId = 0)
{
if (lastId == 0) lastId = long.MaxValue;
var userSpecific =
FeedMessages.Where(fm =>
fm.UserId.HasValue && fm.UserId.Value == userId && fm.Id < lastId && !fm.IsDeleted);
var groupSpecific =
FeedMessages.Where(fm =>
fm.UserId == null && fm.GroupId.HasValue && fm.GroupId.Value == groupId && fm.Id < lastId && !fm.IsDeleted);
var siteWide =
FeedMessages.Where(fm =>
fm.UserId == null && fm.GroupId == null && fm.Id < lastId && !fm.IsDeleted);
var feeds = await
userSpecific.Union(groupSpecific).Union(siteWide)
.OrderByDescending(x => x.Id)
.Take(maxResults)
.ToListAsync();
return feeds.OrderBy(x => x.Id);
}
这里的想法是,我想获取特定于用户,特定于组或通用的记录,按ID进行组织,然后返回前X个结果。
如果运行此命令,则会出现整个屏幕错误:
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Union({from FeedMessage fm in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[MySolution.Common.Entities.FeedMessage]) where ((((([fm].UserId == null) AndAlso ([fm].GroupId != null)) AndAlso (Convert([fm].GroupId, Int32) == __groupId_2)) AndAlso ([fm].Id < __lastId_3)) AndAlso Not([fm].IsDeleted)) select [fm]})' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Union({from FeedMessage fm in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[MySolution.Common.Entities.FeedMessage]) where (((([fm].UserId == null) AndAlso ([fm].GroupId == null)) AndAlso ([fm].Id < __lastId_4)) AndAlso Not([fm].IsDeleted)) select [fm]})' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Union({from FeedMessage fm in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[MySolution.Common.Entities.FeedMessage]) where ((((([fm].UserId == null) AndAlso ([fm].GroupId != null)) AndAlso (Convert([fm].GroupId, Int32) == __groupId_2)) AndAlso ([fm].Id < __lastId_3)) AndAlso Not([fm].IsDeleted)) select [fm]})' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Union({from FeedMessage fm in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[MySolution.Common.Entities.FeedMessage]) where (((([fm].UserId == null) AndAlso ([fm].GroupId == null)) AndAlso ([fm].Id < __lastId_4)) AndAlso Not([fm].IsDeleted)) select [fm]})' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'orderby [x].Id desc' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'Take(__p_5)' could not be translated and will be evaluated locally.
这是怎么回事?我该如何解决?这将是一个很大的表,在本地进行评估会破坏系统。
答案 0 :(得分:0)
我最终在EF Core的github网站上制作了bug report,几个小时后,我得到了可以使用的响应。事实证明,服务器端操作尚不支持Union()
,Concat()
,Except()
和Intersect()
。 :\
在我的网络搜索中没有立即发现这一点。
根据开发团队的建议,我可以这样重写查询:
return FeedMessages
.Where(fm => fm.Id < lastId && !fm.IsDeleted && (
(fm.UserId.HasValue && fm.UserId.Value == userId) ||
(fm.UserId == null && fm.GroupId.HasValue && fm.GroupId.Value == groupId) ||
(fm.UserId == null && fm.GroupId == null)))
.OrderByDescending(x => x.Id)
.Take(maxResults)
.OrderBy(x => x.Id)
.ToListAsync();
...这使我脱离了危机模式,但我想抛给所有EF Core开发人员,看看这些帖子,这是重要的功能,应尽快在现实中优先考虑(IMO)。