我正在使用EF Code First的现有数据库并使用modelBuilder进行配置。我有两个表,其中一个SESSION可以有一个SUBJECT,类是这样的:
public class SessionItem {
[Key]
public int SessionId { get;set; }
// Other Values
public int Subject_ID { get;set; }
public virtual Subject Subject { get;set; }
}
public class SubjectItem {
[Key]
public int Subject_ID { get;set; }
// Other Values
public virtual SessionItem Session { get;set; }
}
然后modelBuilder代码是:
modelBuilder.Entity<SessionItem>().ToTable("tblTblSessions");
modelBuilder.Entity<Subject>().ToTable("tblTblSubjects");
modelBuilder.Entity<SessionItem>()
.HasOptional<Subject>(u => u.Subject)
.WithOptionalDependent(c => c.Session).Map(p => p.MapKey("Subject_ID"));
这首先失败,直到我从SessionItem类中删除了Subject_ID,然后我得到了错误:发生了关系多重性约束违规:EntityReference只能有一个相关对象,但查询返回了多个相关对象。这是一个不可恢复的错误。
知道我哪里出错了吗?
答案 0 :(得分:2)
试试这个:
public class SessionItem
{
[Key]
public int SessionId { get;set; }
// Other Values
[ForeignKey("Subject")]
public int? Subject_ID { get;set; }
[ForeignKey("Subject_ID")]
public virtual SubjectItem Subject { get;set; }
}
您需要使Subject_ID外键可以为空。
答案 1 :(得分:2)
实体框架不支持one-to-one foreign key associations,因为EF不知道唯一的键约束是什么(会话表中的Subject_ID
列显然有)。
您必须通过将关系映射为一对多来解决此问题。按照@ flem对SessionItem
实体的回答进行映射,对于SubjectItem
实体,请完全删除public virtual SessionItem Session { get;set; }
或将其替换为
public virtual ICollection<SessionItem> Sessions { get; set; }
对于此关系,您不再需要使用Fluent API进行映射,或者如果您需要,它应该是:
modelBuilder.Entity<SessionItem>()
.HasOptional(se => se.Subject)
.WithMany() // or WithMany(su => su.Sessions)
.HasForeignKey(se => se.Subject_ID);
当您向该集合添加项目时,您必须在业务逻辑中确保不添加多个项目,因为您的数据库中不能有多个具有相同Subject_ID
的行唯一键约束。从数据库(包括会话)加载主题时,会话集合为空或者只有一个元素,但不能更多。
答案 2 :(得分:1)
[Table("tblTblSessions")]
public class SessionItem {
[Key]
public int SessionId { get; set; }
public virtual SubjectItem Subject { get; set; }
}
[Table("tblTblSubjects")]
public class SubjectItem {
[Key, ForeignKey("Session")]
public int Subject_ID { get; set; }
public virtual SessionItem Session { get; set; }
}
SubjectItem和SessionItem之间的一对一关系,您可以摆脱所有的modelBuilder代码 - 您正在进行的所有表命名和一对一映射都使用上面的属性和属性。
编辑:修正了拼写错误并标记了一对一的从属方。