C# 如何设置与Entity Framework的一对一或零关系,并在子实体上公开外键?

C# 如何设置与Entity Framework的一对一或零关系,并在子实体上公开外键?,c#,asp.net,entity-framework,C#,Asp.net,Entity Framework,我有一个一对一关系的工作配置,如下所示: public class ParentEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; } } public class ChildEntity { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

我有一个一对一关系的工作配置,如下所示:

public class ParentEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; } 
}

public class ChildEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    public Guid ParentId { get; set; }

    [ForeignKey("ParentId")]
    public ParentEntity Parent { get; set; }
}
public class ParentEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; } 
    public virtual ChildEntity Child { get; set; }
}

public class ChildEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public ParentEntity Parent { get; set; }
}
该解决方案已投入生产,运行良好。现在,我需要能够从父实体引用子实体,因此我尝试这样做:

public class ParentEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public virtual ChildEntity Child { get; set; }
}
我收到了这个错误:

System.InvalidOperationExceptionUnable to determine the principal end of an association between the types 'ChildEntity' and 'ParentEntity'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

我遇到了如何使用Fluent API配置原理的问题,但是没有任何东西允许我在
ParentEntity
上添加
ChildEntity
引用,并在
ChildEntity

上维护
ParentId
,在第一个解决方案中,EF正在创建单向一对多关系。为了帮助您更好地了解正在发生的事情,使用Fluent Api对该关系进行的配置如下:

modelBuilder.Entity<ChildEntity>()
            .HasRequired(ce=>ce.Parent)
            .WithMany()
            .HasForeignKey(ce=>ce.ParentId);
但我不认为这是您正在寻找的模型,因为一个
父实体
可能是多个
子实体
的父实体,因此我认为您需要配置一对多关系:

public class ParentEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; } 
    public virtual ChildEntity Child { get; set; }
}

public class ChildEntity
{
    [Key, ForeignKey("Parent")]
    public Guid Id { get; set; }

    public ParentEntity Parent { get; set; }
}
public class ParentEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; } 

    public virtual ICollection<ChildEntity> Children { get; set; }
}

public class ChildEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [ForeignKey("Parent")]
    public Guid ParentId { get; set; }

    public ParentEntity Parent { get; set; }
}
将此Fluent Api配置添加到您的上下文中,以指定谁是关系中的主体和从属关系,并指定您在数据库中已经拥有的FK的名称(您的实体上不能有具有该名称的属性):

modelBuilder.Entity()
.HasRequired(sr=>sr.Parent)
.WithOptional(s=>s.Child)
.Map(c=>c.MapKey(“父Id”);

我明白了。第一种解决方案有效的唯一原因是英孚认为这是一种一对多的关系。我可以添加
ICollection
并使关系正常工作,但数据实际上不是一对多,而是一对一。
modelBuilder.Entity<ChildEntity>()
            .HasRequired(sr => sr.Parent)
            .WithOptional(s => s.Child)
            .Map(c=>c.MapKey("Parent_Id"));