实体框架模型前1:0..1关系 [英] Entity Framework Model First 1:0..1 Relationship

查看:160
本文介绍了实体框架模型前1:0..1关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Visual Studio 2012中的Entity Framework 5模型设计器中创建了以下模型:





然后我从模型生成数据库,这导致我的数据库中的以下表: / p>



请帮助我了解为什么实体框架为一对一关联生成一对多的关系。






更新#1



此外,如果我从1:0更改关联。1到1:1这样:





然而,不仅数据库中还没有一对一的关系,而且现在一对多关系被翻转,这似乎对我来说更奇怪:








更新#2



为了回应Mystere Man的评论和回答,我期望在SQL Server中看到的结构是有效的1:0..1关系如下:





此外,我能够按照预期的方式使其正常工作以下代码第一流利的映射:

  public class UserMap:EntityTypeConfiguration< User> 
{
public UserMap()
{
ToTable(Users);

HasKey(t => t.UserId);

属性(t => t.UserId)
.HasColumnName(UserId);

属性(t => t.Name)
.HasColumnName(Name)
.IsRequired()
.HasMaxLength(50);

属性(t => t.EmailAddress)
.HasColumnName(EmailAddress)
.IsRequired()
.HasMaxLength(254);

属性(t => t.CreatedDateTime)
.HasColumnName(CreatedDateTime);

HasOptional(t => t.Subscription)
.WithRequired(t => t.User);
}
}

public class SubscriptionMap:EntityTypeConfiguration< Subscription>
{
public SubscriptionMap()
{
ToTable(订阅);

HasKey(t => t.SubscriptionId);

属性(t => t.SubscriptionId)
.HasColumnName(SubscriptionId);

属性(t => t.TypeValue)
.HasColumnName(TypeValue);

属性(t => t.CreatedDateTime)
.HasColumnName(CreatedDateTime);

属性(t => t.ExpiresDateTime)
.HasColumnName(ExpiresDateTime);

HasRequired(t => t.User)
.WithOptional(t => t.Subscription);
}
}

所以,我知道有可能实现这个行为代码第一实体框架我的问题是为什么不可以使用Model First方法。



这里发生了什么,为什么?



谢谢!

解决方案

SQL没有办法定义一个真实的1:1或1:0..1数据模型,除非两个实体具有相同的主键。即使如此,您不能拥有1:1,因为您不能在单个语句中的多个表中插入记录,因此数据模型必须允许1:0..1由于存在中间状态其中一条记录将不存在另一条记录。



在SQL中执行此操作的唯一方法是完成EF在此处执行的操作,创建1:*,然后再强制约束确保唯一性(例如唯一约束)。但是,EF不支持约束(您必须手动创建它们),因此可以插入多个记录并违反您的模型。



编辑: p>

既然你已经澄清了你在谈论Model First,而且你正在寻找一个共享的主键,那么这里就是你要做的。



右键单击关联,并在Subscription和User之间创建参照约束。这将导致EF生成您正在寻找的1:0..1关系。


I created the following model in the Entity Framework 5 Model Designer in Visual Studio 2012:

Then I generated the database from the model, which resulted in the following tables in my database:

Please help me understand why Entity Framework is generating a one-to-many relationship for a one-to-zero-or-one association.


Update #1

Furthermore, if I change the association from 1:0..1 to 1:1 like this:

Then not only is there still no one-to-one relationship in the database, but now the one-to-many relationship is flipped around, which seems even more weird to me:


Update #2

In response to Mystere Man's comment and answer, the structure I'm expecting to see in SQL Server, which is a valid 1:0..1 relationship is as follows:

Furthermore, I am able to get this working exactly as intended with the following Code First fluent mapping:

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);
    }
}

So, I know it's possible to achieve this behavior with Code First Entity Framework. My question is why it's not possible to do it with the Model First approach.

What's going on here and why?

Thanks!

解决方案

SQL does not have a way to define a true 1:1 or 1:0..1 data model, except when both entities have the same primary key. Even so, you can't have a 1:1 because you can't insert records into more than one table in a single statement, so the data model has to allow 1:0..1 by virtue of there being a intermediate state where one record will exist without the other.

The only way to do this in SQL is to do exactly what EF is doing here, create a 1:*, and then impose constraints ensure uniqueness (such as a Unique Constraint). However, EF doesn't support constraints (you would have to create them manually) so it's possible to insert more than one record and violate your model.

EDIT:

Since you've clarified that you're talking about Model First, and that you are looking for a shared primary key, then here's what you have to do.

Right click on the Association, and create a referential constraint between Subscription and User. This will then cause EF to generate the 1:0..1 relationship you are looking for.

这篇关于实体框架模型前1:0..1关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆