EFCore 模型无效。以多种方式引用另一个 class 似乎是问题所在?
EFCore Model is invalid. Reference another class from it multiple ways seems to be the problem?
我有一个工作流数据库,其中一部分是 WORKFLOW_INSTANCE,其中有很多 WORKFLOW_STEP_INSTANCE。它工作正常,直到我添加下面的行。
我想说的是一对多但是对于单个WORKFLOW_INSTANCE我也想知道具体的开始工作流程步骤和结束工作流程步骤。为什么会出错?我想我可以只使用 int 并跳过 class 引用吗?
无法确定类型 'WfStepInstance' 的导航 属性 'WfInstance.WfInitialStepInstance' 表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用 'OnModelCreating'.
中的 'EntityTypeBuilder.Ignore' 忽略此 属性
public class WfInstance : Entity
{
public string CreateBy { get; set; }
public DateTime CreatedOn { get; set; }
// n-1 relationship
public int WfStatusTypeId { get; set; }
public WfStatusType WfStatusType { get; set; }
public int WfDefinitionId { get; set; }
public WfDefinition WfDefinition { get; set; }
public int WfActionTypeId { get; set; }
public WfActionType WfActionType { get; set; }
//doesnt work!!!!
public int WfInitialStepInstanceId { get; set; }
public WfStepInstance WfInitialStepInstance { get; set; }
//doesnt work!!!!
//public int WfCurrentStepInstanceId { get; set; }
//public WfStepInstance WfCurrentStepInstance { get; set; }
// 1-n relationship
public List<WfStepInstance> WfStepInstances { get; set; } = new List<WfStepInstance>();
}
public class WfStepInstance : Entity
{
public string Inputs { get; set; }
public string Outputs { get; set; }
public string WaitData { get; set; }
public string CreateBy { get; set; }
public DateTime CreatedOn { get; set; }
// 1-1 relationship
public int? NextStepId { get; set; }
public virtual WfStepInstance NextStep { get; set; }
// n-1 relationship
public int WfInstanceId { get; set; }
public WfInstance WfInstance { get; set; }
public int WfStepStatusTypeId { get; set; }
public WfStepStatusType WfStepStatusType { get; set; }
public int WfStepTypeId { get; set; }
public WfStepType WfStepType { get; set; }
}
我认为问题在于您需要告诉 EF 使用什么 FK。在多对一 (WfInitialStepInstance / WfCurrentStepInstance) 的情况下,EF 使用 Type 来推断键名。
这是可行的,因为类型是 WfActionType,所以约定指向一个名为 WfActionTypeId 的键。
public int WfActionTypeId { get; set; }
public WfActionType WfActionType { get; set; }
这些不起作用,因为约定无法推断 FK 名称,并且您有两个 WfStepInstance 类型的属性。
//doesnt work!!!!
public int WfInitialStepInstanceId { get; set; }
public WfStepInstance WfInitialStepInstance { get; set; }
//doesnt work!!!!
public int WfCurrentStepInstanceId { get; set; }
public WfStepInstance WfCurrentStepInstance { get; set; }
这应该有效..
[ForeignKey("WfInitialStepInstance")]
public int WfInitialStepInstanceId { get; set; }
public WfStepInstance WfInitialStepInstance { get; set; }
[ForeignKey("WfCurrentStepInstance")]
public int WfCurrentStepInstanceId { get; set; }
public WfStepInstance WfCurrentStepInstance { get; set; }
我不太喜欢约定优于配置,因为它在某种程度上滋生了自满情绪,人们可以欣赏它 "just works" 直到它 "just doesn't" 然后被留在没有桨的小溪上,如果他们没有跟上配置的速度。 :)
我建议通过 EntityTypeConfiguration<T>
(EF6)/IEntityTypeConfiguration<T>
(EFCore) 和 DbContext.OnModelCreating
阅读 EF 配置。这将极大地帮助理解 EF 关系是如何映射的,以及当约定不完全适用时您可以做什么。我还建议使用 Shadow Properties (EFCore) 或 Map
+MapKey
(EF6) 而不是在实体中声明 FK 属性。映射的 FK 为实体中的关系提供两个真实来源,并可能导致错误。使用阴影属性,您的实体仅声明导航属性。 FK 是隐藏的。
我有一个工作流数据库,其中一部分是 WORKFLOW_INSTANCE,其中有很多 WORKFLOW_STEP_INSTANCE。它工作正常,直到我添加下面的行。
我想说的是一对多但是对于单个WORKFLOW_INSTANCE我也想知道具体的开始工作流程步骤和结束工作流程步骤。为什么会出错?我想我可以只使用 int 并跳过 class 引用吗?
无法确定类型 'WfStepInstance' 的导航 属性 'WfInstance.WfInitialStepInstance' 表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用 'OnModelCreating'.
中的 'EntityTypeBuilder.Ignore' 忽略此 属性 public class WfInstance : Entity
{
public string CreateBy { get; set; }
public DateTime CreatedOn { get; set; }
// n-1 relationship
public int WfStatusTypeId { get; set; }
public WfStatusType WfStatusType { get; set; }
public int WfDefinitionId { get; set; }
public WfDefinition WfDefinition { get; set; }
public int WfActionTypeId { get; set; }
public WfActionType WfActionType { get; set; }
//doesnt work!!!!
public int WfInitialStepInstanceId { get; set; }
public WfStepInstance WfInitialStepInstance { get; set; }
//doesnt work!!!!
//public int WfCurrentStepInstanceId { get; set; }
//public WfStepInstance WfCurrentStepInstance { get; set; }
// 1-n relationship
public List<WfStepInstance> WfStepInstances { get; set; } = new List<WfStepInstance>();
}
public class WfStepInstance : Entity
{
public string Inputs { get; set; }
public string Outputs { get; set; }
public string WaitData { get; set; }
public string CreateBy { get; set; }
public DateTime CreatedOn { get; set; }
// 1-1 relationship
public int? NextStepId { get; set; }
public virtual WfStepInstance NextStep { get; set; }
// n-1 relationship
public int WfInstanceId { get; set; }
public WfInstance WfInstance { get; set; }
public int WfStepStatusTypeId { get; set; }
public WfStepStatusType WfStepStatusType { get; set; }
public int WfStepTypeId { get; set; }
public WfStepType WfStepType { get; set; }
}
我认为问题在于您需要告诉 EF 使用什么 FK。在多对一 (WfInitialStepInstance / WfCurrentStepInstance) 的情况下,EF 使用 Type 来推断键名。
这是可行的,因为类型是 WfActionType,所以约定指向一个名为 WfActionTypeId 的键。
public int WfActionTypeId { get; set; }
public WfActionType WfActionType { get; set; }
这些不起作用,因为约定无法推断 FK 名称,并且您有两个 WfStepInstance 类型的属性。
//doesnt work!!!!
public int WfInitialStepInstanceId { get; set; }
public WfStepInstance WfInitialStepInstance { get; set; }
//doesnt work!!!!
public int WfCurrentStepInstanceId { get; set; }
public WfStepInstance WfCurrentStepInstance { get; set; }
这应该有效..
[ForeignKey("WfInitialStepInstance")]
public int WfInitialStepInstanceId { get; set; }
public WfStepInstance WfInitialStepInstance { get; set; }
[ForeignKey("WfCurrentStepInstance")]
public int WfCurrentStepInstanceId { get; set; }
public WfStepInstance WfCurrentStepInstance { get; set; }
我不太喜欢约定优于配置,因为它在某种程度上滋生了自满情绪,人们可以欣赏它 "just works" 直到它 "just doesn't" 然后被留在没有桨的小溪上,如果他们没有跟上配置的速度。 :)
我建议通过 EntityTypeConfiguration<T>
(EF6)/IEntityTypeConfiguration<T>
(EFCore) 和 DbContext.OnModelCreating
阅读 EF 配置。这将极大地帮助理解 EF 关系是如何映射的,以及当约定不完全适用时您可以做什么。我还建议使用 Shadow Properties (EFCore) 或 Map
+MapKey
(EF6) 而不是在实体中声明 FK 属性。映射的 FK 为实体中的关系提供两个真实来源,并可能导致错误。使用阴影属性,您的实体仅声明导航属性。 FK 是隐藏的。