public class Child1 { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Name { get; set; } public Child2 Child2 { get; set; } } public class Child2 { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [ForeignKey("Child1")] public int Id { get; set; } public string Name { get; set; } public Child1 Child1 { get; set; } }
当我尝试将一些数据插入数据库时,它抛出异常:
{"A dependent property in a ReferentialConstraint is mapped to a store-generated column. Column: 'Id'."}
看来我不能使用自动生成的Id for Child2,如何保持此功能并同时成功建立关系?
第二个问题仍然没有出现,一对一的关系只是像SQL Server这样的数据库中的理论问题.如果要插入依赖于Child2的Child1,则需要先插入Child1,然后插入相关的Child2.这是正确的,但是,ooops,你还必须在插入Child1之前插入Child2,因为Child1也依赖于Child2.因此,拥有纯粹的一对一关系是不可能的.
要解决这个问题,您需要做两件事:
>使关系为1到0(0或1).即您必须拥有一个可以存在或不存在的主体和一个依赖实体.这将允许您插入主体实体,而不需要依赖实体,因为使用此配置,您可以在没有依赖项的情况下使主体成为必需.
>主PK可以保留为数据库生成,但您必须更改依赖实体上的PK而不是db生成的.因此,当您插入从属实体时,PK(也是FK)可以由EF自由指定.
最后,如果你想到它,一对一的关系通常是没有意义的.您可以使用包含两个表中所有列的单个表,因为当表A中存在一行时,它必须存在于表B中,反之亦然.因此,使用单个表具有相同的效果.
但是,如果您仍想使用1对1关系,EF允许您对其进行建模:
modelBuilder.Entity<Child1>() .HasRequired(c1 => c1.Child2) .WithRequiredPrincipal(c2 => c2.Child1);
请注意,在这种情况下,EF抽象会使您具有一对一的关系,即使它在DB中不存在也是如此.但是,必须使用ModelBuilder指定此关系,因为您需要指定主体和从属端.在这种情况下,主体是Child1,依赖项是Child2.请注意,您仍然需要注意数据库生成值的规则.
请注意,这是使用从Child2到Child1的单个FK而不是从Child1到Child2的FK在DB中建模的.因此,在DB中是(1)到(0或1)关系,如上所述
public class Child1 { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] // Leave as is public int Id { get; set; } ... public class Child2 { //[DatabaseGenerated(DatabaseGeneratedOption.Identity)] [DatabaseGenerated(DatabaseGeneratedOption.None)] // Not db-generated //[ForeignKey("Child1")] -- specified in the model builder public int Id { get; set; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。