【问题标题】:How to migrate an already set up one-to-many relationship in Entity Framework?如何迁移实体框架中已经建立的一对多关系?
【发布时间】:2020-09-29 17:45:34
【问题描述】:

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

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 实现“约定 1”(仅在 Message 类中包含 Contact 对象,仅此而已)。

这个解决方案的问题是我的应用已经发布了,所以我不能简单地改变结构,我需要迁移。我的问题是如何迁移 Fluent API 设置的这种关系

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

【问题讨论】:

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


    【解决方案1】:

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

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

    所以,在这三步修改之后,我在两个表之间建立了一对多的关系,我可以摆脱那个列表。无需其他任何东西,它与旧数据库完美配合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多