【问题标题】:The expression 'x.Taken' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'表达式“x.Taken”在“包含”操作中无效,因为它不代表属性访问:“t => t.MyProperty”
【发布时间】:2021-03-25 11:26:25
【问题描述】:

类塔克:

   
        [Key]    
        public int TaakId { get; set; }
        public int Pid { get; private set; }
        [Required]
        [Range(0,23.5)]
        public double Uur { get; private set; }
        [Required]
        public Functie Functie { get; private set; }
        public List<Taak> Taken { get; private set; }
        [NotMapped]
        public ICollection<WerknemerTaak> Werknemers { get; set; }

类 WerknemerTaak:

  [Required]
        public Werknemer Werknemer { get; set; } 
        [Required]
        public Taak Taak { get; set; }
        
        public Afdelingen Afdeling { get; set; }
        public string Taakbeschrijving { get; set; }

ReadAllTakenWthWerknemers:

  public List<Werknemer> ReadAllWerknemersWithTaken()
        {
            var taken = ctx.Werknemers
                .Include(x => x.Taken)
                .ThenInclude(x => x.Taak)
                .ToList();
            
          
            return taken;
        }

程序.cs

_mgr.GetAllWerknemersWithTaken().ForEach(x =>
                        {
                            Console.WriteLine(x.ToString());
                            Console.WriteLine("Waarvan de taken zijn:");
                            x.Taken.ToList().ForEach(t =>
                            {
                                Console.WriteLine("\t"+t.Taak.ToString());
                            });
                        });

我得到的错误如下:

表达式“x.Taken”在“包含”操作中无效, 因为它不代表属性访问:'t => t.MyProperty'。

我尝试添加 Where(t => t.Werknemer.Pid.Equals(t.Taak.Pid))),但一点运气都没有。我搜索了其他有同样问题的人,但没有找到适合我的答案。而且我需要使用急切加载。

【问题讨论】:

  • ctx.Werknemers 的数据类型是什么?您是否遇到运行时错误或编译时错误?
  • @ChetanRanpariya 我在编译时遇到错误。 ctx.Werknemers 是这个 public DbSet Werknemers { get;放; }
  • WerknemerTaak 类没有 Taken 属性。这就是您收到错误消息的原因。
  • @ChetanRanpariya 不,不是这样。它给了我同样的错误。

标签: c# .net entity-framework eager-loading


【解决方案1】:

Chetan 是正确的,您的 LINQ 表达式混淆了,并且您的实体也有点交织在一起,您应该理顺一下。重命名以使其更具可读性,您可以看到问题:

var taken = ctx.Werknemers  // <- Query over Werknemers...
    .Include(werknemer => werknemer.Taken) // werknemer has no Taken collection...
    .ThenInclude(taak => taak.Taak)
    .ToList();

更改“x”术语不会更改类型,只会使其更具可读性。当您使用智能感知扩展 x. 时,它将概述它正在使用的类型的属性。

这个表达式是针对 Werknemer 实体的,not Taaks。 Wernemers 不包含“Taken”属性,Taak 包含。

这可行:

var taken = ctx.Taaks 
    .Include(x => x.Taken)

或者来自 Werknemers,这应该可以:

var taken = ctx.Werknemers  // <- Query over Werknemers...
    .Include(x => x.Taak)
    .ThenInclude(x => x.Taken) // <- ThenInclude dives into Taak

为了让表达式使用的实体更具可读性:

var taken = ctx.Werknemers  // <- Query over Werknemers...
    .Include(werknemer => werknemer.Taak)
    .ThenInclude(taak => taak.Taken) 

此查询仍将选择 Werknemers,这意味着您需要 Taken Taaks。要获得 Taak,您可以使用 SelectMany。

var taken = ctx.Werknemers  
    // Assuming you would have a `Where` clause to filter the Taken taaks from specific Werk/Taaks...
    .SelectMany(werknemer => werknemer.Taak.Taken);

要预先加载 Taak 的属性,您可以根据 Taak 导航属性在 SelectMany 之后添加 Include 等。

您将面临的下一个问题是 Taak with Taken 内部的自引用循环。 Taak 需要类似可以为空的 ParentTaakId 之类的东西来促进这种关系。对于将在 Taken 集合中的 Taak,需要有一个指向父 Taak 记录的 FK。 EF 将需要配置该关系。

[Key]    
public int TaakId { get; set; }
// ...
public int? ParentTaakId { get; set; }
public List<Taak> Taken { get; private set; }

然后,当您使用 modelBuilder 或 EntityTypeConfiguration 设置映射时:

modelBuilder.Entity<Taak>()
    .HasMany(x => x.Taken)
    .WithOptional()
    .HasForeignKey(x => x.ParentTaakId);

最后,为什么您在 Taak 的 Werknemers 收藏标记为[NotMapped]?由于 Werknemer 具有 Taak 引用,因此该映射应该可以在实体中进行配置。 [NotMapped] 值应谨慎使用,通常应避免使用,因为在 LINQ 表达式中使用它们会导致运行时错误。

【讨论】:

    【解决方案2】:

    所以我在从一些框架代码转换到一些 .NET Core (EF Core) 时遇到了这个错误。原来代码用旧方法编译得很好:

    myQueryable.Include(x => x.SubProp.Select(y => y.SubSubProp));
    

    因此请注意这一点,而是将其(从其他答案中收集)转换为新的 EF Core ThenInclude

    myQueryable.Include(x => x.SubProp).ThenInclude(x => x.SubSubProp);
    

    【讨论】:

    • SelectMany 从未在 Include 中得到支持。应该是Select。
    • 好电话,我会编辑那个错字。不应该在 S.O. :D
    猜你喜欢
    • 1970-01-01
    • 2022-07-11
    • 2022-01-01
    • 1970-01-01
    • 2021-03-07
    • 2021-04-28
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    相关资源
    最近更新 更多