如何迁移 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 是什么?)
我终于找到了解决办法。我不必实施特定的迁移,只需修改以下内容即可:
- 从
OnModelCreating
中删除关系设置
- 上一步导致问题中出现“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; }
}
- 从
Contact
class 中删除消息列表引用 (public ICollection<Message> Messages { get; set; }
)。
因此,在这三步修改之后,我在两个表之间建立了 one-to-many 关系,我可以摆脱该列表。不需要其他任何东西,它与旧数据库完美配合。
我有一个 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 是什么?)
我终于找到了解决办法。我不必实施特定的迁移,只需修改以下内容即可:
- 从
OnModelCreating
中删除关系设置
- 上一步导致问题中出现“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; }
}
- 从
Contact
class 中删除消息列表引用 (public ICollection<Message> Messages { get; set; }
)。
因此,在这三步修改之后,我在两个表之间建立了 one-to-many 关系,我可以摆脱该列表。不需要其他任何东西,它与旧数据库完美配合。