Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF6 - Run Update-Database Command without seeds

I'm Using Entity Framework 6 and I'm using migrations. I have already created the database using an initial migration. Now I have done changes to the Model and the context has changed, and I want to update the database BUT... When I try to run again the Database-Update command the seeds are also running too, and this bring errores due some data is inserted again.

So, how can I to run the Update-Database command WITHOUT running the seed method?


It is hard to believe that EF doesn't have any simple option like -No-Seed for that. I'm almost secure that other ORMs does.

like image 242
Raúl Otaño Avatar asked Feb 20 '15 18:02

Raúl Otaño


3 Answers

From the source code of DbMigrationsConfiguration<TContext>:

/// <summary>
    /// Runs after upgrading to the latest migration to allow seed data to be updated.
    /// 
    /// </summary>
    /// 
    /// <remarks>
    /// Note that the database may already contain seed data when this method runs. This means that
    ///             implementations of this method must check whether or not seed data is present and/or up-to-date
    ///             and then only make changes if necessary and in a non-destructive way. The
    ///             <see cref="M:System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate``1(System.Data.Entity.IDbSet{``0},``0[])"/>
    ///             can be used to help with this, but for seeding large amounts of data it may be necessary to do less
    ///             granular checks if performance is an issue.
    ///             If the <see cref="T:System.Data.Entity.MigrateDatabaseToLatestVersion`2"/> database
    ///             initializer is being used, then this method will be called each time that the initializer runs.
    ///             If one of the <see cref="T:System.Data.Entity.DropCreateDatabaseAlways`1"/>, <see cref="T:System.Data.Entity.DropCreateDatabaseIfModelChanges`1"/>,
    ///             or <see cref="T:System.Data.Entity.CreateDatabaseIfNotExists`1"/> initializers is being used, then this method will not be
    ///             called and the Seed method defined in the initializer should be used instead.
    /// 
    /// </remarks>
    /// <param name="context">Context to be used for updating seed data. </param>

Basically, you don't have another option than implement an "add or update" logic because the Seed method will be executed each time after the initializer is used.

The AddOrUpdate extension method is useful for this, but I have also used this in some cases:

            if (!context.Entities.Any())
            {
                 // Seed
            }
like image 131
Augusto Barreto Avatar answered Nov 03 '22 23:11

Augusto Barreto


From this page:Database initializer and Migrations Seed methods:

The Seed method on the Configuration class runs whenever the Update-Database PowerShell command is executed. Unless the Migrations initializer is being used the Migrations Seed method will not be executed when your application starts.

So, I think you don't have many options here, the migration Seed method always will be called if you run Update-Database command. I was digging if exist a parameter to this command that let you specify not run the Seed method, but I'm fraid it don't exist yet. These are all the parameters you can use (you can find more info in this link):

Update-Database [-SourceMigration <String>] [-TargetMigration <String>] [-Script] [-Force] 
  [-ProjectName <String>] [-StartUpProjectName <String>] [-ConfigurationTypeName <String>] 
  [-ConnectionStringName <String>] [-AppDomainBaseDirectory <String>] [<CommonParameters>]

Update-Database [-SourceMigration <String>] [-TargetMigration <String>] [-Script] [-Force] 
  [-ProjectName <String>] [-StartUpProjectName <String>] [-ConfigurationTypeName <String>] 
  -ConnectionString <String> -ConnectionProviderName <String> 
  [-AppDomainBaseDirectory <String>] [<CommonParameters>]

If you are executing a sql script to insert data in the Seed method, you could use a booleam condition to avoid reinsert the same fields after the first time.

As an aditional info, your request in have a parameter to avoid execute the Seed method when you run the Update-Database command already exist in this site, which is used by EF team to collect suggestions from the community.

like image 4
octavioccl Avatar answered Nov 03 '22 22:11

octavioccl


I moved all my seed statements into separate methods that can be commented out easily before running 'update-database'.

protected override void Seed(Tpsc.EDI.EDIContext context)
{
    try
    {
        //EDI.Seed.DoSeed(context);
    }
    catch (DbEntityValidationException e)
    {
        ...
    }
}
like image 1
geoffb-csharpguy Avatar answered Nov 03 '22 21:11

geoffb-csharpguy