如何迁移实体框架中已经建立的一对多关系?

时间:2020-09-23 13:17:21

标签: c# entity-framework sqlite ef-fluent-api

我有一个C# WPF应用程序,它使用带有SQLite的{​​{1}}数据库。我有一个Entity Framework类,它可以包含多个消息,因此存在一对多关系,请按照以下方式(简化版本)进行设置:

Contact

然后,我通过Fluent API通过以下方式设置关系:

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

我将拥有大量数据(并且也存在这种循环依赖的麻烦,尤其是在以分离模式编辑对象时),因此在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”(仅在Message类中包含Contact对象,仅此而已)。 / p>

此解决方案的问题在于我的应用程序已经发布,因此我不能只是简单地更改结构,我需要进行迁移。我的问题是如何迁移Fluent API设置的这种关系

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

1 个答案:

答案 0 :(得分:0)

最后我找到了解决方案。我不必实施特定的迁移,只需修改以下内容:

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

因此,经过三步修改后,我在两个表之间建立了一对多关系,因此可以摆脱该列表。不需要任何其他功能,它可以与旧数据库完美配合。

相关问题