我正在尝试设计以下实体关系
程序可以有多个程序集。其中一个组件将是一个主组件。每个程序集只属于一个程序。
这些类的建模如下:
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核心的,比如this one,或者提出了重要的逻辑更改,例如this one,甚至是this one,甚至没有编译
答案 0 :(得分:1)
您需要通知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;}
}
答案 1 :(得分:0)
以下代码将满足您的要求。
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
视为可空。