Standardowo w Entity Frameworku dane są seedowane po wgraniu wszystkich migracji. Może to powodować problem, kiedy
wiemy, że dane które seedowaliśmy w przeszłości mogą się zmienić bądź zostać usunięte. W przypadku standardowej implementacji
i użyciu metody AddOrUpdate na DBContexcie te dane zostaną ponownie wstawione do bazy danych. Jak sobie z tym poradzić ?
Zacznijmy od zdefiniowania interfejsu, który nasze migracje będą implementować, ma on postać:
public interface IDbMigrationSeed { void Seed(IDbContext dbContext); }
W tym interfejsie przekazujemy DBContext.
Następnie utwórzmy klasę, w której będą się rejestrować migracje, które wymagania takiego rodzaju seedowania.
public class DbSeederRegister { public static List<IDbMigrationSeed> DbSeeders = new List<IDbMigrationSeed>(); public static void AddDbSeeder(IDbMigrationSeed dbSeeder) { if (dbSeeder != null) { DbSeeders.Add(dbSeeder); } } }
W utworzonej domyślnie klasie Configuration iterujemy po kolekcji DbSeeders.
public abstract class Configuration<T> : DbMigrationsConfiguration<T> where T : DbContext { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(T context) { foreach (var migration in DbSeederRegister.DbSeeders) { migration.Seed(context as IDbContext); context.SaveChanges(); } } }
Ostatnia rzecz, która nam została do implementacji do zarejestrowanie migracji w kolekcji DbSeeders,
Użyję do tego metody rozszerzonej:
public static class DbMigrationExtension { public static void AddSeed(this DbMigration dbMigration) { DbSeederRegister.AddDbSeeder(dbMigration as IDbMigrationSeed); } }
Teraz po uruchomieniu migracji, seed zostanie wgrany tylko raz, wraz z towarzyszącą mu migracją.