我有以下型号:
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,但我无法让它工作,以便Customer
和User
都具有Id
属性身份字段。
答案 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了解详情。
当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。