我有一个奇怪的场景,不知道你能不能帮我.

我有包含一对多关系的实体.在父实体上,我不想添加作为子实体列表的导航属性.相反,我希望它包含子实体的单个实例.在查询时,我会通过子实体的一列来约束子实体.

enter image description here

[Table("parent")]
    public class Parent
    {
        [Key]
        [Column("parentid")]
        public long ParentId { get; set; }

        [Column("name")]
        public string Name { get; set; }

        // This navigation property functions as expected until I go to insert another record into the chil table.
        // Instead the existing record gets updated.
        public Child Child { get; set; }
    }

    [Table("child")]
    public class Child
    {
        [Key]
        [Column("childid")]
        public long ChildId { get; set; }

        [Column("name")]
        public string Name { get; set; }

        public List<Grandchild1> Grandchildren1 { get; set; }

        public List<Grandchild2> Grandchildren2 { get; set; }

        public List<Grandchild3> Grandchildren3 { get; set; }
    }

    [Table("grandchild1")]
    public class Grandchild1
    {
        [Key]
        [Column("grandchildid")]
        public long ChildId { get; set; }
    }

    [Table("grandchild2")]
    public class Grandchild2
    {
        [Key]
        [Column("grandchildid")]
        public long ChildId { get; set; }
    }

    [Table("grandchild3")]
    public class Grandchild3
    {
        [Key]
        [Column("grandchildid")]
        public long ChildId { get; set; }
    }

    public class FamilyDbContext: DbContext
    {
        public DbSet<Parent> Parents { get; set; }

        public DbSet<Child> Children { get; set; }

        public DbSet<Grandchild1> Grandchildren1 { get; set; }

        public DbSet<Grandchild2> Grandchildren2 { get; set; }

        public DbSet<Grandchild3> Grandchildren3 { get; set; }

        public Parent GetParent()
        {
            Parent parent = Parents
                .Include(p => p.Child).ThenInclude(c => c.Grandchildren1)
                .Include(p => p.Child).ThenInclude(c => c.Grandchildren2)
                .Include(p => p.Child).ThenInclude(c => c.Grandchildren3)
                .FirstOrDefault(p =>
                p.Name == "ParentName" &&
                p.Child.Name == "ChildName");
            return parent;
        }
    }

我try 手动创建关系,但随后查询联接到了错误的列.

可能还值得注意的是,我将实际过滤的Child上的字段/列是由枚举支持的.因此,单个父项的子记录数量将是有限的.

我考虑了在Parent上 for each 枚举值设置一个属性的 idea .

推荐答案

格特·阿诺德是正确的.在阅读了他们提供的链接并更好地查看了我的用例之后,我确实需要使用每个层次 struct 的表和鉴别器多态关系.我不能张贴我的确切代码,因为它是为了工作.但我确实改变了上面的例子,以包含我所做的事情.

长话短说.我需要创建我的基本实体的两个子类,并将每个子类的属性添加到父类.我还需要配置EFCore,使其知道将使用单个DB表来保存两个不同类的数据.

  [Table("parent")]
  public class Parent
  {
      [Key]
      [Column("parentid")]
      public long ParentId { get; set; }

      [Column("name")]
      public string Name { get; set; }

      // The following properties are of different class but their data is stored in
      // the same DB table.
      public Son Son { get; set; }

      public Daughter Daughter { get; set; }
  }

  public enum Gender
  {
      Male,
      Female
  }

  // Base class must be marked as abstract or another call to .HasValue on the DB context needs to be made.
  [Table("child")]
  public abstract class Child
  {
      [Key]
      [Column("childid")]
      public long ChildId { get; set; }

      public Gender Gender { get; set; }

      [Column("name")]
      public string Name { get; set; }

      public List<Grandchild1> Grandchildren1 { get; set; }

      public List<Grandchild2> Grandchildren2 { get; set; }

      public List<Grandchild3> Grandchildren3 { get; set; }
  }

  public class Son : Child
  {

  }

  public class Daughter : Child
  {

  }

  [Table("grandchild1")]
  public class Grandchild1
  {
      [Key]
      [Column("grandchildid")]
      public long ChildId { get; set; }
  }

  [Table("grandchild2")]
  public class Grandchild2
  {
      [Key]
      [Column("grandchildid")]
      public long ChildId { get; set; }
  }

  [Table("grandchild3")]
  public class Grandchild3
  {
      [Key]
      [Column("grandchildid")]
      public long ChildId { get; set; }
  }

  public class FamilyDbContext : DbContext
  {
      protected override void OnModelCreating(ModelBuilder builder)
      {
          // This call tells EFCore that the Child entity will contain a column (Gender)
          // that is used to determine if a given record in the DB maps to either a
          // Son or Daughter class based on the value.
          builder.Entity<Child>(c =>
          {
              c.HasDiscriminator(c => c.Gender)
              .HasValue<Son>(Gender.Male)
              .HasValue<Daughter>(Gender.Female);
          });
      }

      public DbSet<Parent> Parents { get; set; }

      public DbSet<Child> Children { get; set; }

      public DbSet<Grandchild1> Grandchildren1 { get; set; }

      public DbSet<Grandchild2> Grandchildren2 { get; set; }

      public DbSet<Grandchild3> Grandchildren3 { get; set; }


      public Parent GetParent()
      {
          Parent parent = Parents
              .Include(p => p.Son).ThenInclude(c => c.Grandchildren1)
              .Include(p => p.Son).ThenInclude(c => c.Grandchildren2)
              .Include(p => p.Son).ThenInclude(c => c.Grandchildren3)
              .FirstOrDefault(p =>
              p.Name == "ParentName" &&
              p.Son.Name == "ChildName");
          return parent;
      }
  }

Csharp相关问答推荐

无法将blob发送到Azure -缺少HTTP标头异常

如何使嵌套for-loop更高效?

Regex在c#中完全匹配

如何在NServicebus中配置学习传输的文件夹(NService bus 8)

返回TyedResults.BadRequest<;字符串>;时问题详细信息不起作用

如何在没有前缀和可选后缀的情况下获取Razor Page Handler方法名称?

单行上的ReSharper数据标注

如何在VS代码中为C#DotNet配置.json选项以调试内部终端的控制台应用程序

N层解决方案上的依赖注入-删除样板

在C#.NET项目中启动时,如何等待提升的PowerShell进程退出?

如何在.NET Maui中将事件与MVVM一起使用?

如何在GRPC代码First服务的返回类型上使用多态性?

为什么我不能从我的异步任务方法中返回异步任务方法?

在集成测试中可以在模拟InMemory数据库中设定数据种子

如何使用Npgsql从SELECT获得所有查询结果

WPF动态设置弹出窗口水平偏移

EF Core 7-忽略模型绑定中的虚拟属性

将列表转换为带有逗号分隔字符串形式的值的字典

LINQ在GROUP BY和JOIN之后获取子列表

如何在flutter dart中使用publicKey.xml文件进行rsa加密,我遇到了问题Exception:Could not parse BigInt