繁体   English   中英

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

[英]One or Zero to One Entity Framework Code First FluentApi

  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); } } 

更复杂的场景:

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);
    }
}

在一对一的关系中,一端必须是主要的 ,第二端必须是依赖的 主要末端是首先插入的末端,可以在没有从属末端的情况下存在。 从属端是必须在主体之后插入的端,因为它具有主体的外键。 配置一对一关系时,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; }
}

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

更新:

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

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

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

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

public class EntityTwo
{
  public int Id { get; set; }
  // public int EntityOneId { get; set; }
  [Required]
  public EntityOne EntityOne { get; set; }
}

我想出来解决这个问题的唯一方法就是创建一个集合和一个辅助属性来表示一个/零一面。 为清楚起见,包括数据注释。

public class EntityOne
{
    [Key]
    public int EntityOneId { get; set; }

    public EntityTwo EntityTwo => EntityTwoNavigation?.FirstOrDefault();
    public ICollection<EntityTwo> EntityTwoNavigation { get; set; }
}

public class EntityTwo
{
    [Key]
    public int EntityTwoId { get; set; }
    public int EntityOneId { get; set; }

    [ForeignKey("EntityOneId")]
    public EntityOne EntityOne { get; set; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM