我在Visual Studio 2012中的Entity Framework 5 Model Designer中创建了以下模型:
然后我从模型中生成了数据库,这导致了我的数据库中的以下表格:
请帮助我理解为什么实体框架为一对一或一对关系生成一对多关系。
更新#1
此外,如果我将关联从1:0..1更改为1:1,如下所示:
然后,不仅数据库中仍然没有一对一的关系,而是现在一对多的关系被翻转,这对我来说似乎更奇怪:
更新#2
在回应Mystere Man的评论和回答时,我希望在SQL Server中看到的结构是一个有效的1:0..1关系,如下所示:
此外,我能够通过以下Code First流畅映射完全按预期工作:
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
ToTable("Users");
HasKey(t => t.UserId);
Property(t => t.UserId)
.HasColumnName("UserId");
Property(t => t.Name)
.HasColumnName("Name")
.IsRequired()
.HasMaxLength(50);
Property(t => t.EmailAddress)
.HasColumnName("EmailAddress")
.IsRequired()
.HasMaxLength(254);
Property(t => t.CreatedDateTime)
.HasColumnName("CreatedDateTime");
HasOptional(t => t.Subscription)
.WithRequired(t => t.User);
}
}
public class SubscriptionMap : EntityTypeConfiguration<Subscription>
{
public SubscriptionMap()
{
ToTable("Subscriptions");
HasKey(t => t.SubscriptionId);
Property(t => t.SubscriptionId)
.HasColumnName("SubscriptionId");
Property(t => t.TypeValue)
.HasColumnName("TypeValue");
Property(t => t.CreatedDateTime)
.HasColumnName("CreatedDateTime");
Property(t => t.ExpiresDateTime)
.HasColumnName("ExpiresDateTime");
HasRequired(t => t.User)
.WithOptional(t => t.Subscription);
}
}
所以,我知道使用Code First Entity Framework可以实现这种行为。我的问题是为什么不能用Model First方法做到这一点。
这里发生了什么以及为什么?
谢谢!
答案 0 :(得分:2)
SQL没有办法定义真正的1:1或1:0..1数据模型,除非两个实体具有相同的主键。即便如此,您也不能拥有1:1,因为您无法在单个语句中将记录插入到多个表中,因此数据模型必须允许1:0..1,因为存在中间状态哪一条记录不存在另一条记录。
在SQL中执行此操作的唯一方法是执行EF在此处执行的操作,创建1:*,然后强制约束以确保唯一性(例如唯一约束)。但是,EF不支持约束(您必须手动创建它们),因此可以插入多个记录并违反您的模型。
编辑:
既然你已经澄清了你所说的Model First,并且你正在寻找一个共享的主键,那么这就是你必须要做的。
右键单击Association,并在Subscription和User之间创建参照约束。这将导致EF生成您正在寻找的1:0..1关系。