EF Core子实体未与父实体一起加载

问题描述

数据库

我正在使用带有两个表的SQL Server数据库:INVOICE_HEADERINVOICE_ROWINVOICE_HEADER有两个字段:

  • INTERNAL_ID,键入int和主键,
  • INV_NUM,键入varchar(13),这对于每个业务逻辑而言都是唯一的,但对于每个数据库结构而言都是唯一的。

INVOICE_ROW具有三个:

  • INTERNAL_ID,键入int和主键,
  • INV_NUM,键入varchar(13)
  • INV_ROW_NUM,键入int,每个业务逻辑也要唯一。

来自INVOICE_ROW的行与INV_NUM的行具有相同的INVOICE_HEADER值,因此在业务逻辑方面构成相同的发票,因此INVOICE_HEADER.INV_NUM和({{1 }},INVOICE_ROW.INV_Num)就我们的查询而言实际上是主键。

INVOICE_ROW.INV_ROW_NUM中找到的值与在INVOICE_HEADER.INTERNAL_ID中找到的值不同,并且两个表中的任何字段似乎都不具有与另一个表中INVOICE_ROW.INTERNAL_ID对应的值。

因此,没有实际的外键将任何一个表链接到另一个表。

我是否需要提及数据库来自第三方,其结构是固定的,具有更多表以及INTERNAL_IDINVOICE_HEADER都具有更多字段?好吧,无论如何我还是这么做的。

实际上,INVOICE_ROW甚至几乎没有出现在描述数据库结构的文档中(逐字段,仅针对其他一些表)。

使用Entity Framework Core访问数据库

由于上述原因,我无法使用数据库中定义的主键。

所以我创建了两个类:

INTERNAL_ID

和上下文:

    public class InvoiceHeader
    {
        public int InternalId { get; set; }
        public string InvoiceNum { get; set; }

        public virtual List<InvoiceRow> InvoiceRows { get; set; }
    }

    public class InvoiceRow
    {
        public int InternalId { get; set; }
        public string InvoiceNum { get; set; }
        public int? RowNum { get; set; }

        public virtual InvoiceHeader InvHeader { get; set; }
    }

我觉得用 public DbSet<InvoiceHeader> RepoInvHeader { get; set; } public DbSet<InvoiceRow> RepoInvRow { get; set; } protected override void OnModelCreating(ModelBuilder p_mbuModel) { base.OnModelCreating(p_mbuModel); // Table name p_mbuModel.Entity<InvoiceHeader>().ToTable("INVOICE_HEADER"); // Primary key p_mbuModel.Entity<InvoiceHeader>().HasKey(t => new { t.InternalId }). HasName("PK_INTERNAL_ID_INVOICE_HEADER"); // Fields p_mbuModel.Entity<InvoiceHeader>().Property(t => t.InternalId).IsRequired(); p_mbuModel.Entity<InvoiceHeader>().Property(t => t.InternalId).HasColumnType("int"); p_mbuModel.Entity<InvoiceHeader>().Property(t => t.InvoiceNum).HasColumnName("INV_NUM"); p_mbuModel.Entity<InvoiceHeader>().Property(t => t.InvoiceNum).HasColumnType("varchar(13)"); p_mbuModel.Entity<InvoiceHeader>().Property(t => t.InvoiceNum).HasMaxLength(13); // Foreign keys p_mbuModel.Entity<InvoiceHeader>().HasMany(h => h.InvoiceRows). WithOne(r => r.InvHeader). HasPrincipalKey(h => h.InvoiceNum). HasForeignKey(r => r.InvoiceNum); // Table name p_mbuModel.Entity<InvoiceRow>().ToTable("INVOICE_ROW"); // Primary key p_mbuModel.Entity<InvoiceRow>().HasKey(t => new { t.InternalId }). HasName("PK_INTERNAL_ID_INVOICE_ROW"); // Fields p_mbuModel.Entity<InvoiceRow>().Property(t => t.InternalId).IsRequired(); p_mbuModel.Entity<InvoiceRow>().Property(t => t.InternalId).HasColumnType("int"); p_mbuModel.Entity<InvoiceRow>().Property(t => t.InvoiceNum).HasColumnName("INV_NUM"); p_mbuModel.Entity<InvoiceRow>().Property(t => t.InvoiceNum).HasColumnType("varchar(13)"); p_mbuModel.Entity<InvoiceRow>().Property(t => t.RowNum).HasColumnName("INV_ROW_NUM"); p_mbuModel.Entity<InvoiceRow>().Property(t => t.RowNum).HasColumnType("int"); // Foreign keys p_mbuModel.Entity<InvoiceRow>().HasOne(r => r.InvHeader). WithMany(h => h.InvoiceRows). HasForeignKey(r => r.InvoiceNum). HasPrincipalKey(h => h.InvoiceNum); } HasMany进行的所有提及都是有必要的,以弥补缺乏真正的,可用的主键。

结果

我尝试了以下操作:

WithOne

在调试时, InvoiceHeader z_objHeader = z_dbcContexteSage.repoInvHeader.Include(h => h.InvoiceRows).FirstOrDefault(h => h.Piece == "XXXX"); 的值应为z_objHeader中字段的期望值,但其INVOICE_HEADER属性为InvoiceRows。 (我也尝试过null:它抛出了foreach (InvoiceRow z_objRow in z_objHeader.InvoiceRows)。)

现在,如果我添加并运行它,

NullReferenceException

查看 InvoiceRow z_objRow = z_dbcContexteSage.repoInvRow.FirstOrDefault(r => r.Piece == "XXXX"); 表示它现在包含一个 z_objHeader.InvoiceRows

跑步后甚至更好

InvoiceRow

List<InvoiceRow> z_lisRows = z_dbcContexteSage.repoInvRow.Where(r => r.Piece == "XXXX").ToList(); 现在具有所有我期望的行。

所以我可以使用它,但是我仍然觉得那些从z_objHeader.InvoiceRows显式加载的命令不是必需的,甚至是有用的。

我在网络上看了很多遍,似乎找不到我忽略或遗忘的地方。

我想抓住的可能是那些官方但无法使用的主键/事实上的主键东西。

有什么想法吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)