Search code examples
c#sql-serverasp.net-coreentity-framework-coredatabase-migration

When I use Seeding in .NET Core app, Only DB Schema Migrates without the dummy data I added before


I expect to see the entered data in the SQL database, only migrations applied without the entered data for testing purposes

This is an example of data seeding, I added real IDs of the Categories to keep the relation reliable between products and categories

I'm using IEntityTypeConfiguration<T> not OnModelCreating in the DbContext

    public class CategoryConfiguration : IEntityTypeConfiguration<Category>
    {
        public void Configure(EntityTypeBuilder<Category> builder)
        {
            builder.HasKey(p => p.Id);

            builder.Property(p => p.Name)
                   .IsRequired();

            builder.HasMany(p => p.Products)
                   .WithOne(p => p.Category)
                   .HasForeignKey(p => p.CategoryId)
                   .OnDelete(DeleteBehavior.SetNull);

            var categories = new List<Category> {

            new Category
            {
                Id = Guid.Parse("bdafc3c9-abe6-4ac5-bdb6-8361524ff999"),
                Name = "Mobile Phones",
                CreateTime = DateTime.Now
            },
            new Category
            {
                Id = Guid.Parse("f5a4eb59-26b3-4784-b427-65b5f7f57052"),
                Name = "Laptops",
                CreateTime = DateTime.Now
            }
            };
            builder.HasData(categories);
        }
    }

    public class ProductConfiguration : IEntityTypeConfiguration<Product>
    {
        public void Configure(EntityTypeBuilder<Product> builder)
        {
            builder.HasKey(p => p.Id);

            builder.Property(p => p.Name)
                   .IsRequired();

            builder.Property(p => p.Price)
                   .IsRequired();

            builder.HasMany(p => p.Images)
                   .WithOne(p => p.Product)
                   .HasForeignKey(p => p.ProductId)
                   .OnDelete(DeleteBehavior.Cascade);

            var products = new List<Product> {
             new Product
            {
                Id = Guid.Parse("2cc1ca42-7f05-48e9-b223-886c5c98a4af"),
                Name = "IPhone 15 Pro",
                Description = "Titanum - 1TB",
                Price = 59.99,
                CategoryId = Guid.Parse("bdafc3c9-abe6-4ac5-bdb6-8361524ff999")
            },
            new Product
            {
                Id = Guid.Parse("c8faaae7-fee5-450c-ac98-0baaa046077d"),
                Name = "IPhone 13",
                Description = "Moonlight - 128GB",
                Price = 29.99,
                CategoryId = Guid.Parse("bdafc3c9-abe6-4ac5-bdb6-8361524ff999")
            },
            new Product
            {
                Id = Guid.Parse("e4b56b1a-6372-4e5b-9f61-03ee2b5e6b64"),
                Name = "MacBook Pro 16-inch",
                Description = "256GB SSD Storage / 8-Core CPU 8-Core GPU 8GB Unified Memory",
                Price = 1500.99,
                CategoryId = Guid.Parse("f5a4eb59-26b3-4784-b427-65b5f7f57052")
            },
            new Product
            {
                Id = Guid.Parse("0d7957d2-2ca7-43eb-b9e0-6e300da1a6b4"),
                Name = "MacBook Air 13-inch",
                Description = "M3 Max / 1TB / 16-core CPU 40-core GPU 48GB Unified Memory",
                Price = 1350.99,
                CategoryId = Guid.Parse("f5a4eb59-26b3-4784-b427-65b5f7f57052")
            }
            };
            builder.HasData(products);
        }
    }

Solution

  • Even when using IEntityTypeConfiguration<T>, you still need to instruct the DbContext to apply these configurations. This is usually achieved in the DbContext class by calling the ApplyConfigurationsFromAssembly method.

    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Automatically applies all IEntityTypeConfiguration classes in the assembly
            modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
    
            base.OnModelCreating(modelBuilder);
        }
    }
    

    After registering the configurations in DbContext, run the migration to ensure that the data seeding is correctly reflected.