Entity Framework 在数据库中添加额外字段。并添加复合键的两个成员

Entity Framework adds extra field in database. and adds both members of composite key

我正在努力处理 Entity Framework 生成的复合键和额外字段。我有一个我认为很奇怪的问题。

假设我与这些class有一对多的关系:

文件(档案)

[Table("Dossier")]
public class Dossier
{
    [Key]
    public string Dossiernummer { get; set; }

    [Key]
    public string Dossierversie { get; set; }

    [Required]
    public string Dossierreferentie { get; set; }

    [Required]
    public string Relatienr { get; set; }

    public ICollection<Artikel> Artikels { get; set; } ();

}

还有我的文章(文章)class:

[Table("Artikel")]
public class Artikel
{
    [Key]
    public string Artnr { get; set; }

    [Key]
    public string ArtVersie { get; set; }

    public string ArtOmschrijving { get; set; }

    public Dossier Dossier { get; set; }

    public string Dossiernummer { get; set; }

}

我正在使用迁移和代码优先方法。出于某种原因,使用迁移会在文章 table 中创建一个 dossiernummer1 列。我不明白为什么,希望它消失。有人知道怎么做吗?

我不想拥有的另一件事是我的文章中的第二个主键 table。它将档案 table 中的两个键都放在文章 table 中,但我只想将 Dossiernummer 用作外键。你知道怎么改吗?

当从上下文中获取所有档案时,我也注意到了一些奇怪的事情。当我查看档案对象时,文章列表是空的,即使数据库中存在相关数据。自己初始化是不是很正常?

感谢您提前提供任何帮助和信息。

亲切的问候,

你必须使用流利的 API 来设置关系并添加 ColumnAttribute 来排序键:

[Table("Artikel")]
public class Artikel
{
    [Key]
    [Column(Order = 1)]
    public string Artnr { get; set; }

    [Key]
    [Column(Order = 2)]
    public string ArtVersie { get; set; }

    public string ArtOmschrijving { get; set; }

    public Dossier Dossier { get; set; }

    public string Dossiernummer { get; set; }

}

[Table("Dossier")]
public class Dossier
{
    [Key]
    [Column(Order = 1)]
    public string Dossiernummer { get; set; }

    [Key]
    [Column(Order = 2)]
    public string Dossierversie { get; set; }

    [Required]
    public string Dossierreferentie { get; set; }

    [Required]
    public string Relatienr { get; set; }

    public ICollection<Artikel> Artikels { get; set; }
}

在您的 dbcontext 中覆盖 OnModelCreating 方法:

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
      base.OnModelCreating(modelBuilder);


        builder.Entity<Dossier>()
               .HasMany(x => x.Artikels)
               .WithOne(a => a.Dossier)
               .HasForeignKey(a => new { a.Dossiernummer, a.Artnr });


        builder.Entity<Artikel>()
        .HasKey(x => new {x.Artnr,x.ArtVersie});

        builder.Entity<Dossier>()
        .HasKey(x => new {x.Dossiernummer,x.Dossierversie});
  }

档案编号 1: Artikel 有一份档案。 EF 知道必须建立一个 K 关系。这就要求Dossier的PK必须包含在Artikel中,想加进去。它发现您已经输入了具有该名称的字段(它不知道是什么),因此将其添加为 Dossiernummer1。您不应该将 Dossiernummer 添加到 Artikel - 除非您确实需要一个用于其他用途 - 因为它存在的唯一原因是 FK。 EF 会为您解决这个问题。

将 Dossierversie 添加到 Artikel: 它认为 Dossier 的 PK 是 Dossiernummer + Dossierversie,因此要指向正确的 Dossier,它必须同时具有 tem。我不使用 code-first 所以我不能建议你 a) 如何指定一个 PK 和另一个单独的索引(我假设这就是你想要的)与复合 PK(这就是你看起来拥有的) ).

Dossier.Artikels 为空:这就是 EF 的工作方式,称为延迟加载。它首先通过不属于它们的任何东西获取 'root' 对象。一旦你的代码访问了一个 Artikels 集合,它应该在那个时候加载它们(对于那个 Dossier)。这可以防止 EF 拉入可能占数据库很大一部分的内容 Imaging an ECommerce system。获取客户列表将提取与该列表中的客户相关的所有订单;这些订单拥有的所有订单行;与这些订单行上的产品相关的所有产品数据等等。这可不是什么好事。相反,它只是获取您特别提到的内容,然后根据需要提取相关项目。

顺便说一句,当将未加载的集合视为所有者的属性时(例如,在加载的 Dossier 上查看 Artikels),VS 中的调试器告诉我检查集合将导致它被加载并给我选择是否继续。