EF6 - 运行没有种子的Update-Database命令

时间:2015-02-20 18:02:52

标签: c# .net entity-framework migration database-migration

我正在使用Entity Framework 6而我正在使用迁移。我已经使用初始迁移创建了数据库。现在我已对模型进行了更改,并且上下文已更改,我想更新数据库但是... 当我再次尝试再次运行Database-Update命令时,种子也在运行,这会因为再次插入一些数据而导致错误。

那么,如何在不运行种子方法的情况下运行Update-Database命令?


很难相信EF没有像-No-Seed这样的简单选项。我几乎可以确保其他ORM的安全。

6 个答案:

答案 0 :(得分:10)

来自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>

基本上,除了实施&#34;添加或更新&#34;之外,您没有其他选择。逻辑因为每次使用初始值设定项后都会执行Seed方法。

AddOrUpdate扩展方法对此很有用,但在某些情况下我也使用了它:

            if (!context.Entities.Any())
            {
                 // Seed
            }

答案 1 :(得分:4)

从此页面:Database initializer and Migrations Seed methods

  

只有Update-Database PowerShell,Seed类上的Configuration方法才会运行   执行命令。除非正在使用迁移初始化程序   您的应用程序将不会执行迁移Seed方法   启动。

因此,我认为您在这里没有很多选项,如果您运行Seed命令,将始终调用迁移Update-Database方法。我正在挖掘是否存在一个参数给这个命令,让你指定不运行Seed方法,但我还没知道它还没有存在。这些是您可以使用的所有参数(您可以在此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>]

如果您正在执行sql脚本以在Seed方法中插入数据,则可以使用booleam条件以避免在第一次之后重新插入相同的字段。

作为附加信息,您的请求中有一个参数,以避免在您运行Seed命令时执行Update-Database方法,此命令已存在于此site中,由EF小组使用收集社区的建议。

答案 2 :(得分:1)

我将所有种子语句移动到单独的方法中,可以在运行'update-database'之前轻松注释掉。

Command "python setup.py egg_info" failed with error code 1 in /private/tmp/pip-build-ns7p77pf/pyobjc-core

答案 3 :(得分:1)

我通常使用命令update-database -sc然后运行生成的脚本来手动更新数据库。 在开始时我没有感觉很舒服,但现在我想看看我的数据库会发生什么事情,为时已晚。

答案 4 :(得分:0)

如果您有用于插入数据的sql脚本,并且希望阻止将来插入,则可以使用 sql merge 来避免重复。将您拥有的所有数据插入到具有与目标表相同结构的临时表中,然后使用合并来决定何时插入记录。如果匹配是因为您插入了一次。

假设S是包含所有数据的临时表,T是最终表

MERGE Target AS T
USING Source AS S
ON (T.EmployeeID = S.EmployeeID AND T.EmployeeName LIKE 'S%' 
    AND S.EmployeeName LIKE 'S%' )
WHEN NOT MATCHED BY TARGET
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName)
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName
WHEN NOT MATCHED BY SOURCE
    THEN DELETE

有关更多参考资料,请使用https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx

答案 5 :(得分:0)

旧问题,但始终有用。因此,我的贡献是:使用web.config / app.config中的ConfigurationManager选项

可以通过配置类访问System.Configuration.ConfigurationManager

以这种方式执行:

public sealed class Configuration : DbMigrationsConfiguration<Booking.EntityFramework.BookingDbContext> {

    public Configuration() {
       // ...
    }

    protected override void Seed(Booking.EntityFramework.BookingDbContext context) {
        // check configuration if seed must be skipped
        if (!bool.Parse(ConfigurationManager.AppSettings["Database.Seed"] ?? bool.TrueString)) return;

        // if here, seed your database
        // ...
    }
}

通过这种方式,您可以在web.config或app.config文件中定义应用程序设置:

<appSettings>
  <add key="Database.Seed" value="false" />  <!-- <== do not seed! -->
  ...
</appSettings>