一个或一个一个实体框架代码第一FluentApi [英] One or Zero to One Entity Framework Code First FluentApi

查看:116
本文介绍了一个或一个一个实体框架代码第一FluentApi的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 我需要创建fluentapi一个或零到一个引用,并在两个实体上都有导航属性。

  2. EntityTwo应该包含存储外键的简单方法(EntityOneId)

      public class EntityOne 
    {
    public int Id {get;组; }
    public EntityTwo EntityTwo {get;组; }
    }

    public class EntityTwo
    {
    public int Id {get;组; }
    public int EntityOneId {get;组; }
    public EntityOne EntityOne {get;组;


    public class MyDbContext:DbContext
    {
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    base.OnModelCreating(modelBuilder );
    //一些代码修剪

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

public EntityTwo EntityTwo {get;组; }
}

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

public EntityTwo EntityTwo {get;组; }
}

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

public int EntityOneId {get;组; }

public EntityOne EntityOne {get;组; }

public int EntityThreeId {get;组; }

public EntityThree EntityThree {get;组;


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

//一些代码修剪

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


解决方案

一对一关系一端必须是主体,而第二端必须依赖。主要的终点是首先被插入,而不依赖的则可以存在。从属的结尾是必须在校长之后插入的,因为它具有校长的外键。配置一对一关系时,实体框架要求从属主键也是外键。实现你想要的方式可以是正确的方式,但是使用数据注释:

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

public class EntityTwo
{
[Key,ForeignKey(EntityOne)]
public int EntityOneId {get;组; }
public virtual EntityOne EntityOne {get;组; }
}

我建议你检查一下这个链接,您可以在这里找到有关EF Code First中一对一关系如何工作的更多信息。 / p>

更新:



恐怕你想要的是不可能的。与未声明为PK的FK的一对一关系。如果您希望每个实体拥有自己的 Id ,可以在该两个实体之间配置一对一的关系,然后删除 EntityTwo 。



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

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

或者您只需添加必需属性在导航属性为主体,例如:

  public class EntityTwo 
{
public int Id {get;组; }
// public int EntityOneId {get;组; }
[必需]
public EntityOne EntityOne {get;组; }
}


  1. I need to create fluentapi one or zero to one reference and have navigation properties on both of entities.
  2. EntityTwo should contain simple proerty to store foreign key (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);
        }
    }
    

more complex scenario:

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

解决方案

In one-to-one relation one end must be principal and second end must be dependent. Principal end is the one which will be inserted first and which can exist without the dependent one. Dependent end is the one which must be inserted after the principal because it has foreign key to the principal. When configuring one-to-one relationships, Entity Framework requires that the primary key of the dependent also be the foreign key. The proper way to achieve what you want could be this, but is using Data Annotations:

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

I suggest you check this link, you can find there more info about how work the one-to-one relationships in EF Code First.

Update:

I am afraid that what you want is not possible.You can't create a one-to-one relation with a FK that is not declared as a PK. If you want to have each Entities with their own Id an configure an one-to-one relationship between that two entities, then delete the FK property in the EntityTwo.

My recomendation is map that relationship using Fluent Api as I show below:

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

Or you can just add the Required attribute over the navigation property that is principal, for example:

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

这篇关于一个或一个一个实体框架代码第一FluentApi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆