.NET Core 6 Scaffolding for migration from 3.1 leaves out many-to-many bridging tables

Viewed 611

So I am migrating a project from .NET Core 3.1 to .NET Core 6 and would like to scaffold a new context class. Here is the SQL for my db:

CREATE TABLE Product 
(
    Product_ID int NOT NULL 
        CONSTRAINT PK_Products PRIMARY KEY CLUSTERED,
    Description varchar(100) NOT NULL 
        CONSTRAINT UC_Product UNIQUE,
);

CREATE TABLE ProductCategory 
(
    ProductCategory_ID int NOT NULL 
        CONSTRAINT PK_ProductCategory PRIMARY KEY CLUSTERED,
    Description varchar(100) NOT NULL 
        CONSTRAINT UC_ProductCategory UNIQUE,
);

CREATE TABLE Product_ProductCategory 
(
    Product_ID int NOT NULL 
        CONSTRAINT FK_ProductProductCategory_Products REFERENCES Product(Product_ID),
    ProductCategory_ID int NOT NULL 
        CONSTRAINT FK_ProductProductCategory_ProductCategory REFERENCES ProductCategory(ProductCategory_ID),
    CONSTRAINT PK_ProductProductCategory 
       PRIMARY KEY CLUSTERED (Product_ID, ProductCategory_ID)
);

Here is the script used to scaffold:

Scaffold-DbContext "Server=.;Database=MyDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer 
    -OutputDir Models -DataAnnotations 
    -Tables Product, ProductCategory, Product_ProductCategory

Using ProductProductCategory instead of Product_ProductCategory has the same result.

Here is the resulting code in my context class:

namespace MyProject.Models
{
    public partial class ProjectContext : DbContext
    {
        public ProjectContext()
        {
        }

        public ProjectContext(DbContextOptions<ProjectContext> options)
            : base(options)
        {
        }

        //why are there only 2 tables here?
        public virtual DbSet<Product> Products { get; set; }
        public virtual DbSet<ProductCategory> ProductCategories { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>(entity =>
            {
                entity.Property(e => e.ProductId).ValueGeneratedNever();

                entity.HasMany(d => d.ProductCategories)
                    .WithMany(p => p.Products)
                    .UsingEntity<Dictionary<string, object>>(
                        "ProductProductCategory",
                        l => l.HasOne<ProductCategory>().WithMany().HasForeignKey("ProductCategoryId").HasConstraintName("FK_ProductProductCategory_ProductCategory"),
                        r => r.HasOne<Product>().WithMany().HasForeignKey("ProductId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_ProductProductCategory_Products"),
                        j =>
                        {
                            j.HasKey("ProductId", "ProductCategoryId").HasName("PK_ProductProductCategory");

                            j.ToTable("Product_ProductCategory");

                            j.IndexerProperty<int>("ProductId").HasColumnName("Product_ID");

                            j.IndexerProperty<int>("ProductCategoryId").HasColumnName("ProductCategory_ID");
                        });
            });

            modelBuilder.Entity<ProductCategory>(entity =>
            {
                entity.Property(e => e.ProductCategoryId).ValueGeneratedNever();
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}

The bridging table is simply missing. In my code for the Core 3.1 project, the bridging tables are referenced frequently and their absence causes a lot of errors regarding missing definitions in my context class. It also fails to generate the entity classes.

Is there any reason Core 6 is ignoring these tables entirely? The code does acknowledge the bridging table, but without an actual definition, it cannot be used.

Note that my full code has over 20 such bridging tables. Adding them in manually is not a trivial task. Original entities were also scaffolded in .NET Core 3.1.

Also, the tables are now pluralized. Is there a way to keep them singular? (.NET Core 3.1 Scaffold was singular, causing yet more problems)

Most importantly, though, how do I get the missing bridging tables?

1 Answers
Related