实体框架1:0或1关系

时间:2015-07-12 20:01:39

标签: entity-framework ef-fluent-api

我有以下型号:

public class User
{
    public int Id { get; set; }
    public Customer Customer { get; set; }
    ...
}

public class Customer
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
    ...
}

我想要的是Customer必须有User,但只能有一个,User不必有Customer

我想使用Fluent API,但我无法让它工作,以便CustomerUser都具有Id属性身份字段。

1 个答案:

答案 0 :(得分:1)

当您配置一对一关系时,Entity Framework要求依赖项的主键也是外键,在您的情况下它将是:

public class User
{
    public int Id { get; set; }
    public virtual Customer Customer { get; set; }
    ...
}

public class Customer
{
    [Key, ForeignKey("User")]
    public int UserId { get; set; }
    public virtual User User { get; set; }
    ...
}

但是你希望每个实体都有自己的PK,所以,EF允许你这样做,但是你应该从UserId实体中删除Customer属性,因为正如我之前所说的,在这种情况下关系FK也必须是PK。要正确配置您的关系,请使用Required数据注释,因为@Claies会在他的评论中推荐您:

public class User
{
    public int Id { get; set; }
    public virtual Customer Customer { get; set; }
    ...
}

public class Customer
{
    [Key]
    public int Id { get; set; }
    [Required]
    public virtual User User { get; set; }
    ...
}

或者你可以使用Fluent Api,配置如下:

modelbuilder.Entity<Customer>().HasRequired(c=>c.User).WithOptional(u=>u.Customer);

另外,我建议您将导航属性定义为virtual。这样,当您第一次查阅这些属性时,它们将被延迟加载。请查看此post了解详情。

更新1:

当key属性为整数时,Code First默认为 DatabaseGeneratedOption.Identity。如果需要,您可以使用客户ID上的[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]属性明确配置所需内容。

public class Customer
{
    [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
}

或者您可以使用Fluent Api:

modelbuilder.Entity<Customer>().HasKey(t => t.Id)
                               .Property(t => t.Id)
                               .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

更新2:

我不明白为什么要抛弃那个例外。我刚刚测试了两种变体(Data Annotations和Fluent Api),一切运行良好。这是迁移生成的代码:

 public partial class changeCustomerIdToIdentity : DbMigration
    {
        public override void Up()
        {
            DropIndex("dbo.Customers", new[] { "Id" });
            DropPrimaryKey("dbo.Customers");
            AlterColumn("dbo.Customers", "Id", c => c.Int(nullable: false, identity: true));
            AddPrimaryKey("dbo.Customers", "Id");
            CreateIndex("dbo.Customers", "Id");
        }

        public override void Down()
        {
            DropIndex("dbo.Customers", new[] { "Id" });
            DropPrimaryKey("dbo.Customers");
            AlterColumn("dbo.Customers", "Id", c => c.Int(nullable: false));
            AddPrimaryKey("dbo.Customers", "Id");
            CreateIndex("dbo.Customers", "Id");
        }
    }

我担心您的错误是由于您的数据库架构而发生的。 Id表上的Customers也必须为FK。该错误意味着您的实体之间存在某种关系,其中依赖实体中的外键属性被定义为存储生成,这是因为您尝试将客户实体的Id更改为Identity,这是您的FK DB。

相关问题