简体   繁体   English

实体框架中的单向一对一关系

[英]Unidirectional One-To-One relationship in Entity Framework

Below example of one-to-one relationship throws an exception 下面的一对一关系示例抛出异常

public class User
{
    public int Id { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public User User { get; set; }
}

Exception says: 例外说:

Unable to determine the principal end of an association between the types 'ConsoleApplication1.Address' and 'ConsoleApplication1.User'. 无法确定类型“ConsoleApplication1.Address”和“ConsoleApplication1.User”之间关联的主要结束。 The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations. 必须使用关系流畅API或数据注释显式配置此关联的主要结尾。

it works if i remove User property from Address but i don't want. 如果我从地址中删除用户属性但我不想要它。

How can i have such a relationship without an exception ? 我怎么能有这样的关系,没有例外?

While the answer provided by Eranga is correct and creates a shared primary key association between User and Address, you might not want to use it due to the limitations this mapping type has. 虽然Eranga提供的答案是正确的,并且在用户和地址之间创建了共享主键关联 ,但由于此映射类型的限制,您可能不想使用它。

Here is another way of creating a 1:1 association which is called one-to-one foreign key association : 以下是创建1:1关联的另一种方法,称为一对一外键关联

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Address>()
                .HasRequired(a => a.User)
                .WithOptional(u => u.Address)
                .Map(m => m.MapKey("UserId"));
}

EF Code First recognizes this as a 1:1 association hence allowing you to have a bidirectional association between User and Address. EF Code First将此识别为1:1关联,因此允许您在用户和地址之间建立双向关联。

Now all you need to do is to define a Unique Key constraint on the UserId column to make your relationship a true one to one on your database side. 现在,您需要做的就是在UserId列上定义一个Unique Key约束,以使您的关系在数据库端真正一对一。 One way for doing so is using a Seed method that has been overridden in a custom initializer class: 这样做的一种方法是使用已在自定义初始化程序类中重写的Seed方法:

class DbInitializer : DropCreateDatabaseAlways<Context>
{
    protected override void Seed(Context context)
    {
        context.Database.ExecuteSqlCommand("ALTER TABLE Addresses ADD CONSTRAINT uc_User UNIQUE(UserId)");
    }
}


The above code will result in the following schema: 上面的代码将产生以下架构:

在此输入图像描述

You need to use fluent API to map the relationship as shared primary key. 您需要使用流畅的API将关系映射为共享主键。

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<Address>()
             .HasRequired(a => a.User)
             .WithOptional(u => u.Address);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM