我是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; }
}
这些实体之间的关系是: EntityParent:
目标是在EntityParent中具有以下属性:
在EntityChildren中,属性:
但是在执行命令以生成数据库脚本时却出现了以下错误:
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 der) 在Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext上下文,IConventionSetBuilder ConventionSetBuilder,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 der) 在Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext上下文,IConventionSetBuilder ConventionSetBuilder,IModelValidator v 滑道)
请帮助
答案 0 :(得分:1)
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; }
}
然后,在ICollection<ParentChildren>
和EntityParent
中使用EntityChild
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);
}
答案 1 :(得分: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属性,必需/可选,级联删除行为等。相应的流利配置为像这样:
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)
;