我有一个现有的sql数据库,其中2个表具有可选的与适当记录的一对一关系。
我为我的asp.net核心web应用程序配置了与实体框架核心的给定关系,如下所示:
// Principal (parent)
public class Person
{
[Key]
public int Id { get; set; }
public string LastName { get; set; }
public virtual Address Address { get; set; }
}
// Dependent (child)
public class Address
{
public int? AddressRef { get; set; }
public string Street { get; set; }
public virtual Person Person { get; set; }
}
modelBuilder.Entity<Person>(entity =>
{
entity.ToTable("Person");
entity.HasKey(k => new { k.Id });
entity.Property(p => p.Id)
.HasColumnName("PersonRef");
});
modelBuilder.Entity<Address>(entity =>
{
entity.ToTable("Address");
entity.HasKey(x => x.AddressRef);
entity.Property(e => e.AddressRef).ValueGeneratedNever();
entity.HasOne(a => a.Person)
.WithOne(b => b.Address)
.HasForeignKey<Address>(c => c.AddressRef)
.IsRequired(false)
.OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_dbo.Address_dbo.Person_AddressRef");
})
当我尝试通过DbContext添加一个新的Person
var newPerson = new Person()
{
LastName = model.LastName,
// ...
};
DbContext.Add(newPerson);
DbContext.SaveChanges() // Error is thrown
我得到ErrorMessage:
Person的值。试图保存更改时,Id'是未知的。这是因为该属性也是关系中主体实体未知的外键的一部分。
我尝试了几种配置一对一关系的变体,但都给出了相同的错误。
任何帮助都将不胜感激。
您的主体实体的主键应该被注释为AutoGeneratedValue。
modelBuilder.Entity<Person>(entity =>
{
entity.ToTable("Person");
entity.HasKey(k => k.Id); // .ValueGeneratedOnAdd(); problem was here
entity.Property(k => k.Id).ValueGeneratedOnAdd(); // <-- Here is the change
entity.Property(k => k.Id)
.HasColumnName("PersonRef");
});
注意:Primiary key
在Principal Entity
中应该有Primary Key
的值,因为它将在Dependent Entity
中用作主键
和@FFad3试图告诉,在你的场景Address
是可选的,而不是Person
,因为我上面提到的地址的主键应该从Person
表上的现有记录映射。如果没有相应的人,就不可能有Address
的记录。
您可以将其更改为一对多关系以使其成为可能。这样,在Person
表中,您将在Address
(可空外键)上有一个Foreign Key
,在Address
实体上有一个单独的Primary key
。
如果你问我,我会告诉你怎么做。
我认为你应该改变
公共虚拟地址地址{get;设置;} =比;公共虚拟地址?地址{get;设置;}
如果Person也检查迁移脚本。Id设置为SqlServer:Identity
Id = table。列(类型:"int",空值:false).Annotation("SqlServer:Identity", " 1,1 ")