C# 一对一实体或零对一实体框架代码优先FluentApi 我需要创建fluentapi一对一或零对一引用,并在这两个实体上都有导航属性

C# 一对一实体或零对一实体框架代码优先FluentApi 我需要创建fluentapi一对一或零对一引用,并在这两个实体上都有导航属性,c#,entity-framework,ef-code-first,ef-fluent-api,C#,Entity Framework,Ef Code First,Ef Fluent Api,EntityTwo应该包含存储外键的简单属性(EntityOneId) 公共类EntityOne { 公共int Id{get;set;} public EntityTwo EntityTwo{get;set;} } 公共类实体2 { 公共int Id{get;set;} public int EntityOneId{get;set;} 公共EntityOne EntityOne{get;set;} } 公共类MyDbContext:DbContext { 模型创建时受保护的覆盖无效(DbMod

EntityTwo应该包含存储外键的简单属性(EntityOneId)

公共类EntityOne
{
公共int Id{get;set;}
public EntityTwo EntityTwo{get;set;}
}
公共类实体2
{
公共int Id{get;set;}
public int EntityOneId{get;set;}
公共EntityOne EntityOne{get;set;}
}
公共类MyDbContext:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//一些代码被删除了
modelBuilder.Entity()
.has可选(entity=>entity.EntityTwo)
.WithRequired();
modelBuilder.Entity()
.HasRequired(entity=>entity.EntityOne)
.有很多
.HasForeignKey(实体=>entity.EntityOneId)
.WillCascadeOnDelete(假);
}
}
更复杂的情况:

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);
    }
}
公共类EntityOne
{
公共int Id{get;set;}
public EntityTwo EntityTwo{get;set;}
}
公共类实体三
{
公共int Id{get;set;}
public EntityTwo EntityTwo{get;set;}
}
公共类实体2
{
公共int Id{get;set;}
public int EntityOneId{get;set;}
公共EntityOne EntityOne{get;set;}
公共int EntityThreeId{get;set;}
公共实体三个实体三{get;set;}
}
公共类MyDbContext:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
//一些代码被删除了
modelBuilder.Entity()
.has可选(entity=>entity.EntityTwo)
.WithRequired();
modelBuilder.Entity()
.has可选(entity=>entity.EntityTwo)
.WithRequired();
modelBuilder.Entity()
.HasRequired(entity=>entity.EntityOne)
.有很多
.HasForeignKey(实体=>entity.EntityOneId)
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.HasRequired(entity=>entity.EntityThree)
.有很多
.HasForeignKey(实体=>entity.EntityThreeId)
.WillCascadeOnDelete(假);
}
}

在一对一关系中,一端必须是主体,另一端必须是依赖的。主端是将首先插入的端,并且可以在没有从属端的情况下存在。从属端是必须插入主体后的端,因为它具有主体的外键。在配置一对一关系时,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代码中一对一关系的信息

更新:
恐怕您想要的是不可能的。您无法创建与未声明为PK的FK的一对一关系。如果要让每个实体都具有自己的
Id
an,请在这两个实体之间配置一对一的关系,然后删除
EntityTwo
中的FK属性

我的建议是使用Fluent Api映射这种关系,如下所示:

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

我想出的处理这个问题的唯一方法是创建一个集合和一个helper属性来表示1/0边,这是公认的有点难看的。为了清晰起见,包含了数据注释

公共类EntityOne
{
[关键]
public int EntityOneId{get;set;}
public EntityTwo EntityTwo=>EntityTwoNavigation?.FirstOrDefault();
公共ICollection EntityTwoNavigation{get;set;}
}
公共类实体2
{
[关键]
public int EntityTwoId{get;set;}
public int EntityOneId{get;set;}
[外键(“EntityOneId”)]
公共EntityOne EntityOne{get;set;}
}

可能从中复制。还是我错了?为了清楚起见,你可以用这个例子。这个例子是有效的,但是它不符合我的期望。我希望EntityTwo有自己的Id,带有指向其他实体的链接(每个链接都是唯一的)Hello@OlegGochachko。不久前我更新了我的答案。您尝试过该配置吗?“您无法创建与未声明为PK的FK的一对一关系。”根据SQL,FK是候选密钥之一就足够了。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<EntityTwo>()
        .HasRequired(et => et.EntityOne)
        .WithOptional(eo=>eo.EntityTwo);
}
public class EntityTwo
{
  public int Id { get; set; }
  // public int EntityOneId { get; set; }
  [Required]
  public EntityOne EntityOne { get; set; }
}