自己参照多対多関係

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で多対多の自己関係を設定したいので、私は2対1の関係を作りました:

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; }
}

私は流暢な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);

しかし、結果私はエラーがあります:

'Ticket.RelatedTickets'と 'Relation.TicketTo'の間には既に関係があるため、 'Ticket.RelatedTickets'と 'Relation.TicketTo'の間に関係を作成することはできません。ナビゲーションプロパティは1つの関係にしか参加できません。

可能な解決策は、Parent関係をTicketEntity直接追加すること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 );
});

しかし、このような親関係を保存するには「汚い」と思われます。
適切なアプローチは何ですか?

受け入れられた回答

リレーションを持つコレクションを1つだけ持つことはできません。あなたはチケットがTicketFrom等しいTicketFromと2つが必要であり、チケットがTicketFrom等しいTicketFromで2つ目が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関連付けone-to-many作成するため、同等ではないことに注意してください。正しく理解すれば、 many-to-manyを求めることになります。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ