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

时间:2012-05-05 22:59:02

标签: c# .net ef-code-first entity-framework-4.3

下面的一对一关系示例抛出异常

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

例外说:

  

无法确定之间关联的主要结束   类型'ConsoleApplication1.Address'和'ConsoleApplication1.User'。   必须明确配置此关联的主要结尾   使用关系流畅的API或数据注释。

如果我从地址中删除User属性但我不想要它。

如何在没有例外的情况下建立这样的关系?

2 个答案:

答案 0 :(得分:13)

虽然Eranga提供的答案是正确的,并且在用户和地址之间创建shared primary key association,但由于此映射类型的限制,您可能不想使用它。

以下是另一种创建1:1关联的方法,称为one-to-one foreign key association

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将此识别为1:1关联,因此允许您在用户和地址之间建立双向关联。

现在,您需要做的就是在UserId列上定义一个Unique Key约束,以使您的关系在数据库端真正一对一。这样做的一种方法是使用在自定义初始化程序类中重写的Seed方法:

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


上面的代码将产生以下架构:

enter image description here

答案 1 :(得分:3)

您需要使用流畅的API将关系映射为共享主键。

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