一个或零到一个实体框架代码First FluentApi

Ole*_*hko 8 c# entity-framework ef-code-first ef-fluent-api

  1. 我需要创建一个或0到一个引用的fluentapi,并在两个实体上都有导航属性.
  2. EntityTwo应该包含存储外键的简单proerty(EntityOneId)

    public class EntityOne
    {
        public int Id { get; set; }
        public EntityTwo EntityTwo { get; set; }
    }
    
    public class EntityTwo
    {
        public int Id { get; set; }
        public int EntityOneId { get; set; }
        public EntityOne EntityOne { get; set; }
    }
    
    public class MyDbContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //some code trimmed
    
            modelBuilder.Entity<EntityOne>()
                .HasOptional(entity => entity.EntityTwo)
                .WithRequired();
    
            modelBuilder.Entity<EntityTwo>()
                .HasRequired(entity => entity.EntityOne)
                .WithMany()
                .HasForeignKey(entity => entity.EntityOneId)
                .WillCascadeOnDelete(false);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

更复杂的场景:

public class EntityOne
{
    public int Id { get; set; }

    public EntityTwo EntityTwo { get; set; }
}

public class EntityThree
{
    public int Id { get; set; }

    public EntityTwo EntityTwo { get; set; }
}

public class EntityTwo
{
    public int Id { get; set; }

    public int EntityOneId { get; set; }

    public EntityOne EntityOne { get; set; }

    public int EntityThreeId { get; set; }

    public EntityThree EntityThree { get; set; }
}

public class MyDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //some code trimmed

        modelBuilder.Entity<EntityOne>()
            .HasOptional(entity => entity.EntityTwo)
            .WithRequired();

        modelBuilder.Entity<EntityThree>()
            .HasOptional(entity => entity.EntityTwo)
            .WithRequired();

        modelBuilder.Entity<EntityTwo>()
            .HasRequired(entity => entity.EntityOne)
            .WithMany()
            .HasForeignKey(entity => entity.EntityOneId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<EntityTwo>()
            .HasRequired(entity => entity.EntityThree)
            .WithMany()
            .HasForeignKey(entity => entity.EntityThreeId)
            .WillCascadeOnDelete(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

oct*_*ccl 12

在一对一的关系中,一端必须是主要的,第二端必须是依赖的.主要末端是将首先插入的末端,并且可以在没有从属末端的情况下存在.从属端是必须在主体之后插入的端,因为它具有主体的外键.配置一对一关系时,Entity Framework要求依赖关系的主键也是外键.实现你想要的东西的正确方法可能是这个,但是使用数据注释:

public class EntityOne
{
  public int Id { get; set; }
  public virtual EntityTwo EntityTwo { get; set; }
}

 public class EntityTwo
 {
   [Key, ForeignKey("EntityOne")]
   public int EntityOneId { get; set; }
   public virtual EntityOne EntityOne { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我建议你查看这个链接,你可以找到更多关于如何在EF Code First中实现一对一关系的信息.

更新:

我担心你想要的是不可能的.你不能与未被宣布为PK的FK建立一对一的关系.如果您希望每个实体都有自己Id的配置,在这两个实体之间建立一对一的关系,那么删除中的FK属性EntityTwo.

我的推荐是使用Fluent Api映射关系,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<EntityTwo>()
        .HasRequired(et => et.EntityOne)
        .WithOptional(eo=>eo.EntityTwo);
}
Run Code Online (Sandbox Code Playgroud)

或者,您只需将Required属性添加到作为主体的导航属性上,例如:

public class EntityTwo
{
  public int Id { get; set; }
  // public int EntityOneId { get; set; }
  [Required]
  public EntityOne EntityOne { get; set; }
}
Run Code Online (Sandbox Code Playgroud)