无法使用EF Code First使用1:1映射将记录保存到数据库

时间:2019-02-15 08:23:11

标签: c# entity-framework

在我的代码中,我有2个“表”,它们具有1到1或1到0的映射。一个person表和一个passport表(我正在显示可复制我的问题的代码,因此请原谅这些示例的人为设计)。这意味着一个人可能没有护照,但是护照必须有一个相关的人。

我遇到的问题是保存时收到以下错误消息

  

ReferentialConstraint中的从属属性映射到商店生成的列。列:“ Id”。

我必须承认,我实际上并不真正理解这里的问题!是的,我可以阅读这些单词,但不知道为什么它在Id列中苦苦挣扎!

这就是我所拥有的

[Table("Person")]
public partial class Person
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public int PassportId {get;set;}

    public virtual Passport Passport {get;set;}
}

[Table("Passport")]
public partial class Passport 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public string PassportDetail { get; set; }

    public virtual Person Person { get; set; }
}

在我的实体(DataContext)中,

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{ 
    modelBuilder.Entity<Person>()              //create for person
            .HasOptional(a => a.Passport)      //a person has optional passport
            .WithRequired(s => s.Person);      //a passport requires a person
}

保存到数据库应该很简单...

var p = new Person();
p.Passport = new Passport()
        {
              PassportDetail = "test"
        };
dataContext.Person.Add(p);
dataContext.SaveChanges();

但是由于上述原因我被告知。

我做错了什么?

A dependent property in a ReferentialConstraint is mapped to a store-generated column之类的帖子似乎非常复杂,并且关于表格定义不当,我希望(著名的最后一句话)我的处境很简单,我避免了这种情况)

A dependent property in a ReferentialConstraint is mapped to a store-generated column error on 1-to-1 relationship中接受的答案似乎表明了该做什么!

此修补程序已更新为

[Table("Passport")]
public partial class Passport 
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]  //changed here
    [Key]
    public int Id { get; set; }
….

但是,如果我这样做了,那么当我将其保存到数据库中时,会因为插入重复项而被告知:(

2 个答案:

答案 0 :(得分:4)

我认为您发现此快速修复方法不是处理EF Code首先意识形态的正确方法,要建立一对一关系,您必须将每个表与另一个表主键进行匹配它是一个int Id,但对于您希望此选项为可选的人,则将其标记为可空,并且EF会生成正确的脚本,以允许创建不带通行证或​​带通行证的人,并且仅允许创建通行证如果与某人有关联

[Table("Person")]
public partial class Person
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public int? PassportId {get;set;}

    public virtual Passport Passport {get;set;}
}

[Table("Passport")]
public partial class Passport 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    public string PassportDetail { get; set; }

    public int PersonId {get;set;}

    public virtual Person Person { get; set; }
}

答案 1 :(得分:2)

实际上,在 sql server 中不可能实现一对一的关系。可以是一对零或一个关系。在您的情况下,一个 Person 将具有一个或零个 Passport ,因此可以简单地建立如下关系,其中主体实体中的 Person 护照是从属实体。

  [Table(“ Person”)]
公共部分阶级的人
{
    [键]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID {get;组; }

    公共PersonName {get; set;}

    公共虚拟护照护照{get; set;}
}

[表格(“护照”)]
公共部分类护照
{
    [Key,ForeignKey(“ Person”)]
    public int PersonId {组; } // <-这里的“ PersonId”既是主键又是外键

    公共字符串PassportDetail {get;组; }

    公共虚拟人Person {组; }
}
 

注意:在此设置中,您不需要任何 Fluent API 配置。

在插入过程中:

  var person = new Person()
{
    PersonName =“测试”
}

护照护照=新护照()
{
      PersonId = person.Id,
      PassportDetail =“测试”
};

dataContext.Persons.Add(person);
dataContext.Passports.Add(passport);
dataContext.SaveChanges();