问题描述
我有一个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表?)
解决方法
最后我找到了解决方案。我不必实施特定的迁移,只需修改以下内容:
- 从
OnModelCreating
删除关系设置 - 上一步导致问题中出现“ 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; }
}
- 从
public ICollection<Message> Messages { get; set; }
类中删除消息列表引用(Contact
)。
因此,经过三步修改后,我在两个表之间建立了一对多关系,因此可以摆脱该列表。不需要任何其他功能,它可以与旧数据库完美配合。