C# 必需到可选关系的实体框架配置

C# 必需到可选关系的实体框架配置,c#,entity-framework,C#,Entity Framework,我对我认为应该是简单的EF关系有一些问题。 我有一个电子邮件实体,它有一个ModerationResult导航属性,而ModerationResult实体有一个ManualModerationReason导航属性 public class Email { public int EmailId { get; set; } public ModerationResult ModerationResult { get; set; } ... } public class Mo

我对我认为应该是简单的EF关系有一些问题。 我有一个电子邮件实体,它有一个ModerationResult导航属性,而ModerationResult实体有一个ManualModerationReason导航属性

public class Email
{
    public int EmailId { get; set; }
    public ModerationResult ModerationResult { get; set; }
    ...
}

public class ModerationResult
{
    public int ModerationResultId { get; set; }
    public ManualModerationReason ManualModerationReason { get; set; }
    ...
}

public class ManualModerationReason
{
    public int ManualModerationReasonId { get; set; }
    public string Reason { get; set; }
    ...
}
我们对电子邮件和审核结果的配置工作正常。电子邮件可以有零个或一个与之关联的审核结果。在我们的数据库中,这样做的结果是,我们有一个ModerationResult表,其中有一个字段“Email\u EmailId”与相关电子邮件相关

下一部分是我遇到的问题。我已将新的ManualModerationReason导航属性添加到ModerationResult。缓和结果可以有零个或一个与之关联的手动缓和原因

我已经为这个新的ManualModerationReason实体创建了DbSet配置,DB现在有一个ManualModerationReason表,包括ManualModerationReasonId和Reason两个字段。这本质上是一个查找表

public DbSet<ManualModerationReason> ManualModerationReason { get; set; }

您不认为您在ManualModerationReason类中缺少导航属性吗

public class ModerationResult
{
   public int ModerationResultId { get; set; }

   public int ManualModerationReasonId { get; set; }

   [ForeignKey("ManualModerationReasonId ")]
   public ManualModerationReason ManualModerationReason { get; set; }

}

public class ManualModerationReason
{
       public int ManualModerationReasonId { get; set; }
       public string Reason { get; set; }

       public List<ModerationResult> ModerationResults { get; set; }

}


modelBuilder.Entity<ManualModerationReason>()
            .HasMany(mreason => mreason.ModerationResults)
            .WithOptional(mresult => mresult.ManualModerationReason)
            .HasForeignKey(mresult => mresult.ManualModerationReasonId);

我想知道为什么您不喜欢将Reason作为另一个属性包含在ModerationResult中?请参阅我对您帖子下方评论的回复,谢谢。如果映射正确,也可能意外创建新记录。我认为您的映射是正确的,但是您应该关注如何向数据库添加新项。请显示一些代码,说明您现在是如何做到这一点的。您是否尝试过。has可选m=>m.ManualModerationReason。使用OptionalDependent?您可以向ModerationResult添加ManualModerationReasonId属性,以便存储FK并将其分配给它,而不是导航属性。这样你就不应该再创建新条目了。好吧,我们真的不需要从ManualModerationReason导航回ModerationResult,如果我们这样做了,它很可能是一个列表,因为将有多个ModerationResult记录都使用相同的ManualModerationReason。但最终,我们想要的是能够从查找表中将ManualModerationReasons中的一个分配给ModerationResult的实例,并将其持久化到DB。我们设想DB只是简单地将相关的ManualModerationReasonId分配给ModerationResult表中的FK字段。
public void Save( Email email )
{
    using ( var ctx = new ModerationContext() )
    {
        ctx.Entry( email ).State = email.EmailId == 0 ? EntityState.Added : EntityState.Modified;

        if ( email.ModerationResult != null )
        {
            ctx.Entry( email.ModerationResult ).State = email.ModerationResult.ModerationResultId == 0 ? EntityState.Added : EntityState.Modified;

            if ( email.ModerationResult.ManualModerationReason != null )
            {
                ctx.Entry( email.ModerationResult.ManualModerationReason ).State = EntityState.Modified;
            }
        }

        ctx.SaveChanges();
    }
}
public class ModerationResult
{
   public int ModerationResultId { get; set; }

   public int ManualModerationReasonId { get; set; }

   [ForeignKey("ManualModerationReasonId ")]
   public ManualModerationReason ManualModerationReason { get; set; }

}

public class ManualModerationReason
{
       public int ManualModerationReasonId { get; set; }
       public string Reason { get; set; }

       public List<ModerationResult> ModerationResults { get; set; }

}


modelBuilder.Entity<ManualModerationReason>()
            .HasMany(mreason => mreason.ModerationResults)
            .WithOptional(mresult => mresult.ManualModerationReason)
            .HasForeignKey(mresult => mresult.ManualModerationReasonId);