asp.net-core - 自引用多对多关系

标签 asp.net-core entity-framework-core

我有一个 Ticket实体:

    public class Ticket
    { 
        public int Id { get; set; }
        public string Title { get; set; }

        public virtual ICollection<Relation> RelatedTickets { get; set; }
    }

我想在 Entity Framework Core 中设置多对多的自关系,所以我做了两个一对多的关系:
public class Relation
{
    [Required, ForeignKey("TicketFrom")]
    public int FromId { get; set; }

    [Required, ForeignKey("TicketTo")]
    public int ToId { get; set; }

    public virtual Ticket TicketFrom { get; set; }
    public virtual Ticket TicketTo { get; set; }
}

我尝试使用 fluent API 创建关系:
        builder.Entity<Relation>()
               .HasKey(uc => new { uc.FromId, uc.ToId });
        builder.Entity<Relation>()
           .HasOne(c => c.TicketFrom)
           .WithMany(p => p.RelatedTickets)
           .HasForeignKey(pc => pc.FromId);
        builder.Entity<Relation>()
           .HasOne(c => c.TicketTo)
           .WithMany(p => p.RelatedTickets)
           .HasForeignKey(pc => pc.ToId);

但结果我有一个错误:

Cannot create a relationship between 'Ticket.RelatedTickets' and 'Relation.TicketTo', because there already is a relationship between 'Ticket.RelatedTickets' and 'Relation.TicketForm'. Navigation properties can only participate in a single relationship.



可能的解决方案是将 Parent 关系直接添加到 TicketEntity :
public class Ticket
{ 
    public int Id { get; set; }

    [Required, ForeignKey("ParentRelation")]
    public Nullable<int> ParentRelationId { get; set; }

    public virtual Ticket ParentRelation {get;set;}

    public virtual ICollection<Ticket> RelatedTickets { get; set; }
    ...
}

像这样流畅的api:
modelBuilder.Entity<Ticket> =>
{
    entity
        .HasMany(e => e.RelatedTickets)
        .WithOne(e => e.ParentRelation) 
        .HasForeignKey(e => e.ParentRelationId );
});

但是像这样存储父关系看起来很“脏”。
什么是正确的方法?

最佳答案

不可能只有一个带有关系的集合。你需要两个 - 一个有关系的票等于 TicketFrom第二个关系票等于TicketTo .

像这样的东西:

模型:

public class Ticket
{ 
    public int Id { get; set; }
    public string Title { get; set; }

    public virtual ICollection<Relation> RelatedTo { get; set; }
    public virtual ICollection<Relation> RelatedFrom { get; set; }
}

public class Relation
{
    public int FromId { get; set; }
    public int ToId { get; set; }

    public virtual Ticket TicketFrom { get; set; }
    public virtual Ticket TicketTo { get; set; }
}

配置:
modelBuilder.Entity<Relation>()
    .HasKey(e => new { e.FromId, e.ToId });

modelBuilder.Entity<Relation>()
    .HasOne(e => e.TicketFrom)
    .WithMany(e => e.RelatedTo)
    .HasForeignKey(e => e.FromId);

modelBuilder.Entity<Relation>()
    .HasOne(e => e.TicketTo)
    .WithMany(e => e.RelatedFrom)
    .HasForeignKey(e => e.ToId);

请注意,使用 Parent 的解决方案并不等效,因为它会创建 one-to-many协会,而如果我理解正确,您正在寻找 many-to-many .

关于asp.net-core - 自引用多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39728016/

相关文章:

c# - 如何在 ASP.NET Core 中间件中获取传入请求正文和传出响应正文?

c# - 拦截并更改应用程序生成的 sql 查询

c# - Entity Framework 7 回滚方法

asp.net-core - 如何在 Identity Server 4 中验证 AAD 用户?

c# - ASP.NET Core 2 没有配置身份验证处理程序来处理方案

c# - 'value' 中的路径必须以 '/' 开头。参数名称 : value

c# - 如何从 IdentityUserRole 转换为 IdentityRole (ASP.NET Core)

c# - 如何通过 FromSqlRaw 调用 EF Core 3.0 中的存储过程

.net - EDMX在哪里

c# - EF Core 1.1 迁移 - 当前的 CSharpHelper 无法构建类型文字