【问题标题】:CodeFirst configuration error creation reason?CodeFirst 配置错误创建原因?
【发布时间】:2018-09-10 08:56:06
【问题描述】:

我是 EntityFramework Core Code 第一个数据库生成的初学者,我对两个实体的关系配置有疑问:

 public class EntityParent
    {
        public int Id { get; set; }
        public string Name { get; set; }

        //Navigation properties to the EntityChildren which have info of start position.
        [ForeignKey("TransformationEntity")]
        public int? TransformationEntityId { get; set; }
        public virtual EntityChildren TransformationEntity { get; set; }

        //Navigation property : List of childrens
        public virtual ICollection<EntityChildren> Childrens { get; set; }
    }

    public class EntityChildren
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int StartPosition { get; set; }

        //List of EntityParents which have this EntityChildren as the start position
        public virtual ICollection<EntityParent> TransformedParents { get; set; }

        //Relation one-to-one(this same table)
        [ForeignKey("EntityChildrenSource")]
        public int? Cadrage { get; set; }
        public virtual EntityChildren EntityChildrenSource { get; set; }
        public virtual EntityChildren EntityChildrenTarget { get; set; }

        //Navigation property to EntityParent
        [ForeignKey("Parent")]
        public int Parent_FK { get; set; }
        public virtual EntityParent Parent { get; set; }
    }

这些实体之间的关系是: 实体父级:

  • 有一个或多个 EntityChild 类型的子级(第一个关系)
  • 有零个或一个 EntityChild 类型的转换(第二个关系)

目标是在 EntityParent 中拥有属性:

  • 孩子名单。
  • 包含起始位置的 EntityChildren。

在 EntityChildren 中的属性:

  • 以该实体为起始位置的 EntityParent 列表
  • 此 EntityChildren 的 EntityParent
  • EntityChildrenSource
  • EntityChildrenTarget

但是在执行生成数据库脚本的命令时出现以下错误:

System.Reflection.TargetInvocationException:调用的目标已抛出异常。 ---> System.InvalidOperationException: 无法确定由“ICollection”类型的导航属性“EntityChildren.TransformedParents”表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。 在 Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyMappingValidationConvention.Apply(InternalModelBuilder modelBuilder) 在 Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuil 德) 在 Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext 上下文,IConventionSetBuilder 约定SetBuilder,IModelValidator v 验证器)

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: **Unable to determine the relationship represented by navigation property 'EntityChildren.TransformedParents' of type 'ICollection<EntityParent>'**. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

在 Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyMappingValidationConvention.Apply(InternalModelBuilder modelBuilder) 在 Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuil 德) 在 Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext 上下文,IConventionSetBuilder 约定SetBuilder,IModelValidator v 验证器)

请帮忙

【问题讨论】:

    标签: c# asp.net-mvc entity-framework-core


    【解决方案1】:

    在 EF Core 中,每个 relationship 包含 0、1 或 2 个导航属性。在大多数情况下,EF Core 可以自动确定关系及其关联的导航属性。但有时它不能,因此它会抛出异常,并希望您通过数据注释、流式 API 或两者的组合来明确指定。

    在这种特殊情况下,异常消息告诉您 EF Core 无法确定 EntityChildren.TransformedParents 集合导航属性表示的关系。您可以通过使用[InverseProperty] 数据注释将其与ParentEntity.TransformationEntity 引用导航属性配对来解决它:

    [InverseProperty(nameof(EntityParent.TransformationEntity))]
    public virtual ICollection<EntityParent> TransformedParents { get; set; }
    

    在这种特殊情况下应该足够了。

    Fluent API 更加灵活,因为它们允许完全配置关系的所有方面 - 主体、依赖、导航属性、依赖 FK 属性、主体 PK 属性、必需/可选、级联删除行为等。相应的 fluent 配置是像这样:

    modelBuilder.Entity<EntityParent>()
        .HasOne(p => p.TransformationEntity)
        .WithMany(c => c.TransformedParents)
        .HasForeignKey(p => p.TransformationEntityId) // optional (by convention)
        .IsRequired(false) // optional (by convention)
        .OnDelete(DeleteBehavior.ClientSetNull) // optional (by convention)
        ;
    

    【讨论】:

      【解决方案2】:
      public class EntityChildren
      {
           public virtual ICollection<EntityParent> TransformedParents { get; set; }    
      

      public class EntityParent
      {
           public virtual ICollection<EntityChildren> Childrens { get; set; }
      

      创建 EF Core 不支持的多对多关系。

      中间类必须解决这个问题

      比如一个类中间类ParentChildren

       public class ParentChildren
       {
              public int ParentId { get; set; }
              public EntityParent Parent{ get; set; }
      
              public int ChildId { get; set; }
              public EntityChild Child{ get; set; }
       }
      

      然后,在您的EntityParentEntityChild 中使用ICollection&lt;ParentChildren&gt;

      DBContext

      protected override void OnModelCreating(ModelBuilder modelBuilder)
          {
              modelBuilder.Entity<EntityParent>()
                  .HasKey(x => x.Id);
      
              modelBuilder.Entity<EntityChild>()
                  .HasKey(x => x.Id);
      
              modelBuilder.Entity<ParentChildren>()
                  .HasKey(x => new { x.ParentId , x.ChildId });
      
              modelBuilder.Entity<ParentChildren>()
                  .HasOne(x => x.Parent)
                  .WithMany(m => m.Childrens)
                  .HasForeignKey(x => x.ParentId);
      
              modelBuilder.Entity<ParentChildren>()
                  .HasOne(x => x.Child)
                  .WithMany(e => e.TransformedParents)
                  .HasForeignKey(x => x.ChildId);
          }
      

      【讨论】:

      • 我忘记指出这些实体之间的关系是: EntityParent : - 有一个或多个 EntityChild 类型的孩子(第一个关系) - 有零个或一个 EntityChild 类型的转换(第二个关系) 这是可以通过上面的方案解决吗?
      猜你喜欢
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 2017-05-22
      相关资源
      最近更新 更多