繁体   English   中英

对于相同的实体类型,一对一和一对多

[英]One to One and One to Many for the same entity type

我正在尝试设计以下实体关系

  • 程序
  • 部件

程序可以有多个程序集。 其中一个组件将是一个主组件。 每个程序集只属于一个程序。

这些类的建模如下:

public class Program
{
    public int Id {get;set;}
    public virtual ProgramAssembly MainAssembly {get;set;}
    public virtual ICollection<ProgramAssembly> Assemblies {get;set;}
}

public class ProgramAssembly
{
   public int Id {get;set;}
   public virtual Program Program {get;set;}
   public int ProgramId {get;set;}
}

我没有用FluentApi指定任何东西(但是,我没有反对它)。
使用上面的代码,我收到此错误:

保存不公开其关系的外键属性的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常源。 通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。 有关详细信息,请参阅InnerException。

InnerException:无法确定依赖操作的有效排序。 由于外键约束,模型要求或存储生成的值,可能存在依赖关系。

我尝试将ProgramAssembly更改为以下内容

public class ProgramAssembly
{
    [ForeignKkey("Program")]
    public int Id {get;set;}
    public virtual Program Program {get;set;}
}

但是,我得到这个错误:

ProgramAssembly_Program_Source ::多重性在关系'ProgramAssembly_Program'中的角色'ProgramAssembly_Program_Source'中无效。 由于“从属角色”是指关键属性,因此从属角色的多重性的上限必须为“1”。

我还尝试了以下流畅的API方法

modelBuilder.Entity<ProgramAssembly>()
   .HasRequired(a => a.Program)
   .WithMany(p => p.Assemblies);

public class ProgramAssembly
    {        
        public int Id { get; set; }
        public virtual Program Program { get; set; }
        [ForeignKey("Program")] //same error with or without this attribute
        public int ProgramId { get; set; }
   }

然后错误是:

保存不公开其关系的外键属性的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常源。 通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。 有关详细信息,请参阅InnerException。 UpdateException:无法确定依赖操作的有效排序。 由于外键约束,模型要求或存储生成的值,可能存在依赖关系。

如何在不改变在Assembly上添加'IsPrimary'属性的方法的情况下允许该关系?

我在SO上看到了一些类似的问题,但它们或者是关于EF核心的,就像这个 ,或者建议像这样的重大逻辑变化,或者甚至那个甚至不编译的逻辑变化。

您需要通知EF您的主键和外键如何工作。 您需要添加属性来定义主键[Key]并定义外键并向导航属性添加属性以定义作为外键的字段。

public class Program
{
    [Key]
    public int Id {get;set;}
    public int MainAssemblyId {get;set;}
    [ForeignKey("MainAssemblyId ")]
    public virtual ProgramAssembly MainAssembly {get;set;}
    public virtual ICollection<ProgramAssembly> Assemblies {get;set;}
}

public class ProgramAssembly
{
   [Key]
   public int Id {get;set;}
   [ForeignKey("ProgramId")]
   public virtual Program Program {get;set;}
   public int ProgramId {get;set;}
}

下面的代码将满足您的要求。

public class Program
{
    [Key]
    public int Id {get;set;}
    public virtual ICollection<ProgramAssembly> Assemblies {get;set;}
}

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

   [ForeignKey("ProgramId")]
   public virtual Program Program {get;set;}
   public int ProgramId {get;set;}
   public bool IsMainProgramAssembly
}

如果需要,可以将[Required]用于ProgramId ,或者也可以将ProgramId为可为空。

暂无
暂无

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

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