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

The expression 'x.Taken' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'

class 塔克:

   
        [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; }

class 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;
        }

Program.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());
                            });
                        });

我得到的错误如下:

The expression 'x.Taken' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'.

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

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

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

更改“x”项不会更改类型,只会使其更具可读性。当您使用 intellisense 展开 x. 时,它将概述正在使用的类型的属性。

这个表达式是针对 Werknemer 实体的,不是 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。要获得 Taaks,您可以使用 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 中的 self-referencing 循环。 Taak 需要类似 null-able ParentTaakId 之类的东西来促进这种关系。对于将在 Taken collection 中的 Taak,需要有一个 FK 指向回 parent Taak 记录。 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 collection 标记为 [NotMapped]?由于 Werknemer 有一个 Taak 引用,这个映射应该可以在实体内配置。 [NotMapped] 值应谨慎使用,通常应避免使用,因为在 LINQ 表达式中使用它们会导致运行时错误。

所以我在从一些 Framework 代码转换为一些 .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);