EF Core:无法翻译查询 - 但在 LinqPad

时间:2021-05-20 21:18:34

标签: c# linq linq-to-sql entity-framework-core

我有一个有点复杂的数据模型,如下所示:

一个文档可以由其他文档组成。 文档可以是项目的一部分。 一个文档可以有不同的版本(代),这些版本也是共享相同密钥的文档。 文档具有状态(已发布或正在编辑等)。

一个项目属于一个版本。 一个项目可以有清单和任务。 任务基于任务模板。

我的数据库中有一个连接这些数据的视图,我想获取所有顶级文档的最新版本(以及该文档的最新发布版本,如果有的话)和项目他们属于(如果有一个活跃的)。如果有项目,我也想得到清单、任务和任务模板。

我的查询如下所示:

var docs =
            (
                // Latest version of a top-level document
                from topLevelDoc in _dbContext.MyView
                    .Where(x => x.IsTopLevel)
                    .GroupBy(x => x.DocumentKey)
                    .Select(grp => grp.OrderByDescending(x => x.Revision).First())
                    .OrderBy(x => x.Title)

                // Last released version of the same document
                let lastReleasedDoc = _dbContext.Document
                    .Where(x => x.DocumentKey == topLevelDoc.DocumentKey && x.State == "Released")
                    .OrderByDescending(x => x.Revision)
                    .FirstOrDefault()

                // The active project
                let project = _dbContext.Project.FirstOrDefault(x =>
                    x.Id == topLevelDoc.ProjectId && !new[] {"Complete", "Cancelled"}.Contains(x.State))

                // The release
                let release =
                    _dbContext.Release.FirstOrDefault(x => x.Id == project.ReleaseId)

                // The checklist
                let checklist = _dbContext.Checklist.FirstOrDefault(x => x.Id == project.ChecklistId)

                let projectTasks =
                    (from projectTask in _dbContext.ProjectTask
                        join taskTemplate in _dbContext.TaskTemplate on projectTask.TaskTemplateId equals taskTemplate.Id
                        where projectTask.ProjectId == project.Id
                        select new {ProjectTask = projectTask, TaskTemplate = taskTemplate})

                select new TopLevelDocument
                {
                    // [...]

                    Project = project != null
                        ? new Project
                        {
                            // [...]
                            Release = new Release
                            {
                                // [...]
                            },
                            Checklist = checklist != null
                                ? new Checklist
                                {
                                    // [...]
                                }
                                : null,
                            Tasks = projectTasks.Select(x =>
                                new ProjectTask
                                {
                                    // [...]
                                    Template = new TaskTemplate
                                    {
                                        // [...]
                                    }
                                }
                            ).ToArray()
                        }
                        : null
                }
            ).ToArray();

虽然这在 LinqPad 中有效,但 EntityFramework Core 3.1.15(我必须使用 .NET Framework 并且更高版本似乎不兼容)正在抱怨:

'System.InvalidOperationException' in Microsoft.EntityFrameworkCore.Relational.dll
The LINQ expression '(GroupByShaperExpression:
KeySelector: (d.document_key), 
ElementSelector:(EntityShaperExpression: 
    EntityType: MyView Keyless
    ValueBufferExpression: 
        (ProjectionBindingExpression: EmptyProjectionMember)
    IsNullable: False
)
)
    .OrderByDescending(x => x.Revision)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

我做错了什么?

仅供参考,我可以通过创建第二个这样的视图并查询来解决这个问题:

CREATE VIEW
LatestRevisionView
AS
SELECT TOP 1 WITH TIES *
FROM MyView
ORDER BY ROW_NUMBER() OVER (PARTITION BY Document_Key ORDER BY Revision DESC)

0 个答案:

没有答案