使用新的 EF Core 5.0 将一对多迁移到多对多

Migrating One-to-Many to Many-to-Many with the new EF Core 5.0

我有一个 ASP.NET Core 5 项目(从 ASP.NET Core 3.1 迁移而来)。 该项目使用 EF Core。

EF Core 5 内置了对多对多的支持。我第一次从 3.1 迁移到 5.0 的主要原因。

现在我的项目有一对多关系,我想将其转换为多对多关系。

这样的关系迁移可能吗?

当前代码:

    public class File
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid UniqueId { get; set; }

    public int RecordId { get; set; }

    public virtual Record Record { get; set; }
    // ...
}


public class Record
{
    [Key]
    public int Id { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid UniqueId { get; set; }

    public virtual ICollection<File> Files { get; set; }
}


  public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
  {

    public DbSet<File> Files { get; set; }
    public DbSet<Record> Records { get; set; }

     protected override void OnModelCreating(ModelBuilder builder)
     {
         base.OnModelCreating(builder);

         builder.Entity<Record>().ToTable("Record");

         // for creating GUIDs   
         builder.Entity<Record>().Property(x => x.UniqueId).HasDefaultValueSql("newid()");
         builder.Entity<File>().Property(x => x.UniqueId).HasDefaultValueSql("newid()");
     }

  }

在上面的代码中,您可以看到一条记录有零个、一个或多个文件。一个文件只有一个关联的记录。

我想更改此设置,以便可以将单个文件分配给多个记录(这样我可以减少重复文件并减少磁盘 space,通过增加缓存命中率等来改善网络流量...) .

在 File-class 中,我是否只需删除这些代码行:

public int RecordId { get; set; }

public virtual Record Record { get; set; }

并将其替换为下面的这一行?

public virtual ICollection<Record> Records { get; set; }

我不想破坏和手动更改数千个文件记录关系...或破坏它们。

  1. public int RecordId { get;放; } // 不要删除

    public虚拟记录记录{get;放; }` 改为

    public 虚拟 ICollection 记录 { get;放; }

2.add实体

public class FileRecord
{
    public int FileId { get; set; }
    public File File { get; set; }

    public int RecordId { get; set; }
    public Record Record { get; set; }
}
  1. public DbSet FileRecords { get;放; }

entity.HasOne(d => d.Record)
                .WithMany(p => p.Files)
                .HasForeignKey(d => d.RecordId);

改为

entity.HasMany(d => d. Records)
                .WithMany(p => p.Files)
                .UsingEntity<FileRecord>(
                j => j
                .HasOne(pt => pt.Record)
                .WithMany()
                .HasForeignKey(pt => pt.RecordId),
            j => j
                .HasOne(pt => pt.File)
                .WithMany()
                .HasForeignKey(pt => pt.FileId),
            j =>
            {
                j.HasKey(t => new { t.TeamId, t.RecordId });
            });

5.Add-迁移

In created migration file add
        protected override void Up(MigrationBuilder migrationBuilder)
{
    //……
    migrationBuilder.Sql("INSERT INTO FileRecords (FileId, RecordId) SELECT Files.Id, Files.RecordId FROM Files");
}

6.Check就可以了,去掉文件class中的public int RecordId { get; set; } 和添加迁移