EF Core表达式正在本地评估...为什么?

时间:2018-11-02 00:06:23

标签: c# entity-framework entity-framework-core

我的数据库上下文中有一个如下所示的方法:

    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.

这是怎么回事?我该如何解决?这将是一个很大的表,在本地进行评估会破坏系统。

1 个答案:

答案 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)。