实体类型EF迁移中有多个导航



我目前正在一个模式模型上制作EF迁移脚本,这个模式模型看起来像

public class Schema : RootId
{
public int Version { get; set; }
[ForeignKey("entity_id")]
public virtual ICollection<Entity> Entities { get; set; } = null!;
[ForeignKey("entity_id")]
public virtual ICollection<Entity> Relations { get; set; } = null!;
}

在这里,两种关系使用相同的对象类型,当我进行迁移时,我会得到错误

There are multiple navigations in entity type 'Schema' which are pointing to same set of properties using a [ForeignKey] attribute: 'entity_id'

这是真的,因为它们两者的外键都是entity_id。但这以前也起过作用,但当时的类型是ICollection<Relation>,它是Entity的完整副本,这没有意义,因为这会引入代码复制。

如何将Relations转换为ICollection<Entity>,并且仍然能够使用foreign_key entity_id?我不知道更改类型是如何使其混淆的?

更新:

好吧,我试过这样做,然后

public class Schema : RootId
{
public int Version { get; set; }
[ForeignKey("entity_id")]
public virtual ICollection<Entity> Entities { get; set; } = null!;
[ForeignKey("entity_id")]
public virtual ICollection<Relation> Relations { get; set; } = null!;
}

public class Entity : BaseEntity
{
} 
public class Relation : BaseEntity
{
} 

public class BaseEntity : RootId
{
} 

但这会导致和外键冲突,每次我插入或更新表时?。。。

"Key (attribute_entity_id)=(4) is not present in table "relation"."

您可以通过对模型进行一点更改来修复它。只需为实体和关系集合定义不同的外键。

public class Schema
{
public int Id { get; set; }
public int Version { get; set; }
public virtual ICollection<Entity> Entities { get; set; } = null!;
public virtual ICollection<Entity> Relations { get; set; } = null!;
}
public class Entity
{
public int Id { get; set; }
public int SchemaAsEntityId { get; set; }
[ForeignKey("SchemaAsEntityId")]
public Schema SchemaAsEntity { get; set; }
public int SchemaAsRelationId { get; set; }
[ForeignKey("SchemaAsRelationId")]
public Schema SchemaAsRelation { get; set; }
}

因为一个实体同时与另一个模型生成多个外键,所以您需要在OnModelCreating:中进行这些配置

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Schema>().HasMany(x => x.Entities).WithOne(x => x.SchemaAsEntity)
.HasForeignKey(x => x.SchemaAsEntityId).IsRequired().OnDelete(DeleteBehavior.ClientSetNull);
modelBuilder.Entity<Schema>().HasMany(x => x.Relations).WithOne(x => x.SchemaAsRelation)
.HasForeignKey(x => x.SchemaAsRelationId).IsRequired().OnDelete(DeleteBehavior.ClientSetNull);
}

您的实际数据模型看起来不起作用,想象一下:如果你从";模式";表,包括链接的";实体";对象,EF Core将无法判断是否存在";实体";必须在Entites集合或Relation集合中。

尽管你说";这个";以前确实在工作:

这以前也起过作用,但当时的类型是ICollection,它是实体的完整副本,这没有意义,因为这会引入代码重复。

如果是这样的话;关系";对象/表。为了避免代码重复,您可以简单地使用继承

class Relation : Entity {}

这意味着一个关系表和一个实体表,但没有代码重复。

我已经看到了你的编辑,我不能发表评论,但为了更好地理解你的新问题,你能显示执行的查询吗?

您在这里基本上试图简化的是对实体类说,它需要有两个相同的外键。当您将[ForeignKey]属性添加到这样的集合中时,这意味着您希望在目标表上创建外键——在这种情况下,该表是实体,并且实体不能有两个具有相同名称的外键。为什么对于两种不同的关系,您希望使用相同的外键?没有足够的上下文让我直接帮助你,但你可以尝试为每个关系制作两个不同的外键。例如:

public class Schema : RootId
{
public int Version { get; set; }
[ForeignKey("schema_Id")]
public virtual ICollection<Entity> Entities { get; set; } = null!;
[ForeignKey("schema_Id")]
public virtual ICollection<Relation> Relations { get; set; } = null!;
}

我认为这将解决你的问题

最新更新