我正在使用Entity Framework 6而我正在使用迁移。我已经使用初始迁移创建了数据库。现在我已对模型进行了更改,并且上下文已更改,我想更新数据库但是...
当我再次尝试再次运行Database-Update
命令时,种子也在运行,这会因为再次插入一些数据而导致错误。
Update-Database
命令?很难相信EF没有像-No-Seed
这样的简单选项。我几乎可以确保其他ORM的安全。
答案 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>