私は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
を求めることになります。