asp.net 同一实体上的多对多(EF核心)[重复]

ruyhziif  于 2023-05-19  发布在  .NET
关注(0)|答案(2)|浏览(129)

此问题已在此处有答案

How can I add an Entity Framework Core n-m self-referencing entity using an explicit join table with payload for SQL-Server?(1个答案)
Many-to-many self referencing relationship(1个答案)
6天前关闭。
我有一个Station实体(在公交车站的上下文中)。此站点实体具有表示目的地的站点集合。如何在EF Core中将其Map为多对多关系?

public class Station {

        [Key]
        public int StationId { get; set; }
        
        [Required]
        [Column(TypeName = "VARCHAR")]
        [StringLength(100)]
        public string TerminalName { get; set; }
        
        [Required]
        [Column(TypeName = "VARCHAR")]
        [StringLength(100)]
        public string City { get; set; }

        [Required]
        [Column(TypeName = "VARCHAR")]
        [StringLength(100)]
        public string Province { get; set; }

        public ICollection<Station> Destinations { get; set; }
    }

我在做这个的时候遇到了麻烦,在为此运行迁移时,它产生了这个错误:
The navigation 'Station.Destinations' cannot be used for both sides of a many-to-many relationship. Many-to-many relationships must use two distinct navigation properties.

qf9go6mv

qf9go6mv1#

我们无法以一流的方式对无向图进行建模。链接表必须有一个FromStation,ToStation,如果你总是可以双向,你需要两个条目。所以试着

public class Station
{

    [Key]
    public int StationId { get; set; }

    [Required]
    [Column(TypeName = "VARCHAR")]
    [StringLength(100)]
    public string TerminalName { get; set; }

    [Required]
    [Column(TypeName = "VARCHAR")]
    [StringLength(100)]
    public string City { get; set; }

    [Required]
    [Column(TypeName = "VARCHAR")]
    [StringLength(100)]
    public string Province { get; set; }

    public ICollection<Station> IncomingDestinations { get; set; }
    public ICollection<Station> OutgoingDestinations { get; set; }
}
5q4ezhmt

5q4ezhmt2#

首先你需要这个额外的类

public class Mapped_Stations
{
    public int OriginId { get; set; }

    public int DestinationId { get; set; }

    public Station Origin { get; set; }

    public Station Destination { get; set; }
}

接下来在你的电台类中添加两个列表

public class Station
{
    [Key]
    public int StationId { get; set; }

    [Required]
    [Column(TypeName = "VARCHAR")]
    [StringLength(100)]
    public string TerminalName { get; set; }

    [Required]
    [Column(TypeName = "VARCHAR")]
    [StringLength(100)]
    public string City { get; set; }

    [Required]
    [Column(TypeName = "VARCHAR")]
    [StringLength(100)]
    public string Province { get; set; }

    //Add This Lists
    public List<Mapped_Stations> Origins { get; set; }
    public List<Mapped_Stations> Destinations { get; set; }
}

然后创建一个Map文件夹,并在该文件夹中添加类,并使用IEntityTypeConfiguration

public class Mapped_SatationsMap : IEntityTypeConfiguration<Mapped_Stations>
{
    public void Configure(EntityTypeBuilder<Mapped_Stations> builder)
    {
        builder.HasKey(t => new { t.OriginId, t.DestinationId });
        builder
            .HasOne(t => t.Origin)
            .WithMany(p => p.Origins)
            .HasForeignKey(f => f.OriginId);
        builder
            .HasOne(t => t.Destination)
            .WithMany(p => p.Destinations)
            .HasForeignKey(f => f.DestinationId).OnDelete(DeleteBehavior.Restrict);
    }
}

最后配置Db

public class Db:DbContext
{
    public Db() : base() { }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.UseSqlServer(@"Server=(local);Database=StackOverFlow;Trusted_Connection=True");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new Mapped_SatationsMap());
    }

    DbSet<Mapped_Stations> Mapped_Stations { get; set; }
    DbSet<Station> stations { get; set; }
}

相关问题