如何迁移 Entity Framework 中已经建立的一对多关系?

How to migrate an already set up one-to-many relationship in Entity Framework?

我有一个 C# WPF 应用程序使用 SQLite 数据库和 Entity Framework。我有一个Contact class可以有多个消息,所以是一对多的关系,设置如下(简化版):

public class Message {
    public int PK { get; set; }
    public int SenderKey { get; set; }
    public Contact Sender { get; set; }
}

public class Contact {
    public int PK { get; set; }
    public ICollection<Message> Messages { get; set; }
}

然后我使用 Fluent API 设置关系,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    ...
    modelBuilder.Entity<Message>()
                .HasOptional(e => e.Sender)
                .WithMany(e => e.Messages)
                .HasForeignKey(e => e.SenderKey);
}

我将有大量数据(并且这种循环依赖也有很多麻烦,尤其是在分离模式下编辑对象时)所以拥有那个 Messages 集合不是一个好主意在每一次接触的记忆中。为避免这种情况,我想摆脱该列表,因此从 the docs 实现 'Convention 1' 会很好(只在消息 class 中包含联系人对象,并且仅此而已)。

此解决方案的问题是我的应用程序已经发布,所以我不能简单地更改结构,我需要迁移。我的问题是,如何迁移由 Fluent API 建立的这种关系?

我试图从 OnModelCreating 中删除关系,但在启动应用程序时出现以下异常: System.Data.SQLite.SQLiteException: SQL logic error no such column: Extent1.Sender_PK(Extent1 table 是什么?)

我终于找到了解决办法。我不必实施特定的迁移,只需修改以下内容即可:

  1. OnModelCreating
  2. 中删除关系设置
  3. 上一步导致问题中出现“sql 逻辑错误”。这是因为未指定外键列名,Entity Framework 搜索默认列,实际上是 Sender_PK。因此,为了解决这个问题,我在 Message class 中添加了一个注释,它告诉 Entity Framework 那个 Contact 对象的外键列名称是什么:
public class Message {
    public int PK { get; set; }
    
    public int SenderKey { get; set; }
    [ForeignKey("SenderKey")]
    public Contact Sender { get; set; }
}
  1. Contact class 中删除消息列表引用 (public ICollection<Message> Messages { get; set; })。

因此,在这三步修改之后,我在两个表之间建立了 one-to-many 关系,我可以摆脱该列表。不需要其他任何东西,它与旧数据库完美配合。