EF核心左外部联接失败,且可为空的对象必须具有一个值

时间:2019-06-28 18:24:10

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

我目前正在努力处理EntityFramework Core查询。 基本上,我正在应用“左外联接”(其他“内联接”除外)。

第一个表是Solutions,基本上是基础,一个单独的表'SolutionViews'跟踪view的每个Solution,因此,假设ID为1的解决方案有2个视图,您将在SolutionViews中找到2行,它们指向SolutionId。最后,我根据SolutionId汇总所有行,以获取每个解决方案的总观看次数。

这是我基本上想复制的SQL查询:

SELECT solution.Id, solution.Name, category.Name, Count(solutionView.SolutionId) As 'Views'
FROM Solutions solution
JOIN Categories category on solution.CategoryId = category.Id
LEFT JOIN SolutionViews solutionView on solution.Id = solutionView.SolutionId
GROUP BY solution.Id, solution.Name, category.Name
ORDER BY Views desc

该查询的结果如下:

Id  Name        CategoryId  Name        Views
9   Solution4   3           Category1   3
1   Solution1   1           Category2   2
2   Solution2   2           Category1   1
8   Solution3   3           Category3   0
10  Solution5   3           Category3   0

使用EF Core 2.1,我首先尝试仅使用LINQ进行所谓的“流利”语法(因为我喜欢这个概念),但是切换到以下查询语法:

    var query = (from solution in context.Solutions
                 join category in context.Categories
                 on solution.CategoryId equals category.Id
                 join view in context.SolutionViews.GroupBy(sv => sv.SolutionId)
                     .Select(g => new {
                         SolutionId = g.Key,
                         Views = g.Count()
                     })
                 on solution.Id equals view.SolutionId into a
                 from b in a.DefaultIfEmpty()
                 select new SolutionWithViewsDto {
                     Solution = solution,
                     Views = b == null ? 0 : b.Views
                 }
        );

我省略了OrderBy,因为稍后我会根据API搜索规范动态添加该订单,但现在此查询为我提供了一个例外: System.InvalidOperationException:“可为空的对象必须具有一个值。”

我很确定,这是因为某些记录在SolutionViews表中没有任何条目,因此我做的LEFT OUTER JOIN错误。

1 个答案:

答案 0 :(得分:0)

信用归Ivan Stoev所有,我只是为此提供一个可见的答案。查询语法似乎有点问题,但最后所做的工作仅使用collapseone_2,这也更加容易。我要做的就是在Navigation Properties导航属性上应用.Count(),这将为您提供每个SolutionsView记录的观看次数。

Solution