【问题标题】:EF Core 3.0 Select Projection with index overload (aka .Select((entity, index) => new {}) fails具有索引重载的 EF Core 3.0 选择投影(又名 .Select((entity, index) => new {})失败
【发布时间】:2020-07-20 21:52:00
【问题描述】:

我有当前设置,带有 Select indexer-projection (entity, index)(请参阅 SubRubrics)。如果我不使用索引器,问题就解决了……但是,如果我不使用 SubRubricItems,那么我可以使用索引器。是仅在我可以使用的最后一个选择投影上,还是..?

以下 linq 投影、错误消息和更多信息。

await _db
                        .Exams
                        .AsNoTracking()
                        .Include(exam => exam.Stations)
                        .ThenInclude(station => station.Rubrics)
                        .ThenInclude(rubric => rubric.SubRubrics)
                        .ThenInclude(subRubric => subRubric.Items)
                        .Select(exam => new Result.ExamViewModel
                        {
                            Id = exam.Id,
                            Name = exam.Name,
                            Stations = exam.Stations.Select(station => new Result.StationViewModel
                            {
                                Id = station.Id,
                                Description = station.Description,
                                Rubrics = station.Rubrics.Select(rubric => new Result.RubricViewModel
                                {
                                    Id = rubric.Id,
                                    Name = rubric.Name,
                                    Info = rubric.Info,
                                    SubRubrics = rubric.SubRubrics.Select((subRubric, index) => new Result.SubRubricViewModel
                                    {
                                        Id = subRubric.Id,
                                        Order = index,
                                        Name = subRubric.Name,
                                        Info = subRubric.Info,
                                        Type = subRubric.Type.ToString(),
                                        Items = subRubric.Items.Select(item => new Result.SubRubricItemViewModel
                                        {
                                            Id = item.Id,
                                            Name = item.Name
                                        })
                                    })
                                })
                            })
                        })
                        .ToListAsync()

这提供了这个我不明白的错误:/

InvalidOperationException: Processing of the LINQ expression '(MaterializeCollectionNavigation(
    navigation: Navigation: Rubric.SubRubrics,
    subquery: (NavigationExpansionExpression
        Source: DbSet<SubRubric>
            .Where(s0 => !(s0.IsDeleted))
            .Where(s0 => EF.Property<Nullable<long>>(r, "Id") != null && EF.Property<Nullable<long>>(r, "Id") == EF.Property<Nullable<long>>(s0, "RubricId"))
        PendingSelector: s0 => (NavigationTreeExpression
            Value: (EntityReference: SubRubric | IncludePaths: Items)
            Expression: s0)
    )
        .Where(i => EF.Property<Nullable<long>>((NavigationTreeExpression
            Value: (EntityReference: Rubric | IncludePaths: Version SubRubrics->...)
            Expression: r), "Id") != null && EF.Property<Nullable<long>>((NavigationTreeExpression
            Value: (EntityReference: Rubric | IncludePaths: Version SubRubrics->...)
            Expression: r), "Id") == EF.Property<Nullable<long>>(i, "RubricId")))
    .AsQueryable()
    .Select((subRubric, index) => new SubRubricViewModel{ 
        Id = subRubric.Id, 
        Order = index, 
        Name = subRubric.Name, 
        Info = subRubric.Info, 
        Type = subRubric.Type.ToString(), 
        Items = subRubric.Items
            .AsQueryable()
            .Select(item => new SubRubricItemViewModel{ 
                Id = item.Id, 
                Name = item.Name 
            }
            ) 
    }
    )' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.

这曾经可以工作,直到我为 Items 模型添加了额外的 SubRubricItems 选择,又名

Items = subRubric.Items.Select(item => new Result.SubRubricItemViewModel
                                        {
                                            Id = item.Id,
                                            Name = item.Name
                                        })

为了参考,这是投影到的视图模型:

public sealed class Result
        {
            public IEnumerable<ExamViewModel> Exams { get; set; }

            public sealed class ExamViewModel
            {
                public long Id { get; set; }
                public string Name { get; set; }
                public IEnumerable<StationViewModel> Stations { get; set; }
            }

            public sealed class StationViewModel
            {
                public long Id { get; set; }
                public string Description { get; set; }
                public IEnumerable<RubricViewModel> Rubrics { get; set; }
            }

            public sealed class RubricViewModel
            {
                public long Id { get; set; }
                public string Name { get; set; }
                public string Info { get; set; }
                public IEnumerable<SubRubricViewModel> SubRubrics { get; set; }
            }

            public sealed class SubRubricViewModel
            {
                public long Id { get; set; }
                public int Order { get; set; }
                public string Name { get; set; }
                public string Info { get; set; }
                public string Type { get; set; }
                public IEnumerable<SubRubricItemViewModel> Items { get; set; }
            }

            public sealed class SubRubricItemViewModel
            {
                public long Id { get; set; }
                public int Order { get; set; }
                public string Name { get; set; }
                public string Info { get; set; }
                public string Type { get; set; }
            }
        }

【问题讨论】:

    标签: entity-framework .net-core ef-core-3.0


    【解决方案1】:

    不能翻译成 SQL。所以要么在.Select()之前运行SQL查询,

    .ThenInclude(subRubric => subRubric.Items)
    .AsEnumerable()
    .Select(exam => new Result.ExamViewModel
    

    或删除Includes(当您有自定义投影时它们不会做任何事情,从而更改查询)

    SubRubrics = rubric.SubRubrics.Select((subRubric) => new Result.SubRubricViewModel
    {
        Id = subRubric.Id,
        Order = 0, . . .
    

    然后在视图模型上填写Order 属性。

    【讨论】:

    • "或删除包含(当您有自定义投影时不执行任何操作),并更改查询":=> 哦,好的,谢谢,就是我不熟悉的东西。它在文档中的某个地方吗?
    • 它可能应该是 doc'd。但是由于您的结果类型与实体类型不同,因此无法使用预先加载的导航属性。
    • 它可以在没有 Include 语句的情况下工作,我认为无论我之后是否更改它都必须提供它们。我一定完全误读了文档,然后误解了这一点。感谢您的反馈。我会尽快标记。
    猜你喜欢
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 2021-06-04
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 2021-06-04
    相关资源
    最近更新 更多