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 或数据注释显式配置。

如果我从地址中删除用户属性但我不想要,它会起作用。

我怎么能毫无例外地建立这样的关系?

4

2 回答 2

13

虽然 Eranga 提供的答案是正确的,并在用户和地址之间创建了一个共享的主键关联,但由于此映射类型的限制,您可能不想使用它。

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

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

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


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

在此处输入图像描述

于 2012-05-08T01:21:56.847 回答
3

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

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<Address>()
             .HasRequired(a => a.User)
             .WithOptional(u => u.Address);
    }
}
于 2012-05-06T00:42:18.487 回答