Entity Framework Migrations - Enable AutoMigrations along with added migration

后端 未结 6 1577
青春惊慌失措
青春惊慌失措 2021-02-04 09:34

I\'m utilizing Entity Framework 4.3 Migrations in my project. I would like to use Automatic migrations so that when I make modifications to my domain objects and my context cla

6条回答
  •  逝去的感伤
    2021-02-04 10:08

    Same solution that Roger did but using an static constructor on the DbContext. Full code below.... this allow the initialization code to live on the class itself and is self-invoked at the first instantiation of the DataDbContext class.

    public partial class DataDbContext : DbContext
    {
        public DataDbContext()
            : base("name=DefaultConnection")
        {
        }
    
        static DataDbContext() // This is an enhancement to Roger's answer
        {
            Database.SetInitializer(new DataDbInitializer()); 
    
            var configuration = new DataDbConfiguration();
            var migrator = new DbMigrator(configuration);
    
            if (migrator.GetPendingMigrations().Any())
                migrator.Update();
        }
    
        // DbSet's
        public DbSet CountryRegion { get; set; }
        // bla bla bla.....
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove();
            modelBuilder.Conventions.Remove();
            modelBuilder.Conventions.Remove();
    
            Configuration.ProxyCreationEnabled = false;
            Configuration.LazyLoadingEnabled = false;
            //Configuration.ValidateOnSaveEnabled = false; 
    
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); // Discover and apply all EntityTypeConfiguration of this assembly, it will discover (*)
        }
    
    }
    
    internal sealed class DataDbInitializer : MigrateDatabaseToLatestVersion
    {
    }
    
    
    internal sealed class DataDbConfiguration : DbMigrationsConfiguration
    {
        public DataDbConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }
    
        protected override void Seed(DataDbContext context)
        {
            DataSeedInitializer.Seed(context); 
            base.Seed(context);
        }
    }
    
    internal static class DataSeedInitializer
    {
        public static void Seed(DataDbContext context)
        {
            SeedCountryRegion.Seed(context);
            // bla bla bla.....
    
            context.SaveChanges();
        }
    }
    
    internal static class SeedCountryRegion
    {
        public static void Seed(DataDbContext context)
        {
            context.CountryRegion.AddOrUpdate(countryRegion => countryRegion.Id,
    
                new CountryRegion { Id = "AF", Name = "Afghanistan" },
                new CountryRegion { Id = "AL", Name = "Albania" },
                // bla bla bla.....
    
                new CountryRegion { Id = "ZW", Name = "Zimbabwe" });
    
            context.SaveChanges();
        }
    }
    
    public class CountryRegionConfiguration : EntityTypeConfiguration // (*) Discovered by
    {
        public CountryRegionConfiguration()
        {
            Property(e => e.Id)
                .IsRequired()
                .HasMaxLength(3);
    
            Property(e => e.Name)
                .IsRequired()
                .HasMaxLength(50);
        }
    }
    
    public partial class CountryRegion : IEntity
    {
        // Primary key 
        public string Id { get; set; }
    
        public string Name { get; set; }
    
    }
    
    public abstract class Entity : IEntity
    {
        //Primary key
        public abstract T Id { get; set; }
    }
    
    public interface IEntity
    {
        T Id { get; set; }
    }
    

    We can see that the Seed method is running again and again.. We can avoid this by checking if a migration already exits, since one is applied automatically when the database is create.. then we can refactor the DataDbConfiguration as follows...

    internal sealed class DataDbConfiguration : DbMigrationsConfiguration
    {
        private readonly bool _isInitialized;
    
        public DataDbConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
    
            var migrator = new DbMigrator(this);
    
            _isInitialized = migrator.GetDatabaseMigrations().Any();
        }
    
        protected override void Seed(DataDbContext context)
        {
            InitializeDatabase(context);
        }
    
        public void InitializeDatabase(DataDbContext context)
        {
    
            if (!_isInitialized)
            {
                if (context.Database.Connection.ConnectionString.Contains("localdb"))
                {
                    DataSeedInitializer.Seed(context); // Seed Initial Test Data
                }
                else
                {
                    // Do Seed Initial Production Data here
                }
    
            }
            else
            {
                // Do any recurrent Seed here
            }
        }
    }
    

提交回复
热议问题