[英]DbMigrator.Update resulting in a Database 'name' already exists
I am using EF code first for a web api system but the use of a DbMigrator in the Configuration for my context results in a SqlException: 我首先使用EF代码用于web api系统,但是在我的上下文配置中使用DbMigrator会导致SqlException:
ystem.Data.SqlClient.SqlException: System.Data.SqlClient.SqlException: Database 'name' already exists. Choose a different database name..
this is with the code: 这是代码:
public Configuration()
{
AutomaticMigrationsEnabled = true;
var dbMigrator = new DbMigrator(this);
// This is required to detect changes.
var pendingMigrationsExist = dbMigrator.GetPendingMigrations().Any();
if (pendingMigrationsExist)
{
dbMigrator.Update();
}
}
without the call to dbMigrator.Update()
the seed method is not executed. 如果没有调用
dbMigrator.Update()
,则不会执行种子方法。
How do I get the seed method to run without this problem? 如何在没有此问题的情况下运行种子方法?
Removing the dbMigrator.Update()
call allows the system to create the DB, but no data is seeded. 删除
dbMigrator.Update()
调用允许系统创建数据库,但不会播种数据。
Note: I am using a CreateDatabaseIfNotExists initialiser, and this is set withing the constructor of the context: 注意:我正在使用CreateDatabaseIfNotExists初始化器,并且使用上下文的构造函数设置:
public MyContext() : base("name=myconnectionstringname")
{
Database.SetInitializer(new CreateDatabaseIfNotExists<MyContext>());
}
Edit: add information on context: 编辑:添加有关上下文的信息:
public class TelephonyContext : DbContext
{
private const string Key = "ddd412345fdee012ddd41e3456789012";
private const string Iv = "fab41e34567fk012";
public TelephonyContext()
: base("name=telephony-connection")
{
var encryptedPassword = ConfigurationManager.AppSettings["telephony-pass"];
var password = AesEncryption.Decrypt(encryptedPassword, Key, Iv);
Database.Connection.ConnectionString = Database.Connection.ConnectionString.Replace("XXXXXX", password);
Database.SetInitializer(new CreateDatabaseIfNotExists<TelephonyContext>());
}
public virtual DbSet<SoftphoneUser> SoftphoneUserSet { get; set; }
public virtual DbSet<InitialCall> InitialCallSet { get; set; }
public virtual DbSet<CallAudit> CallAuditSet { get; set; }
public virtual DbSet<RecordingErrorType> RecordingErrorTypeSet { get; set; }
public virtual DbSet<SourceApplication> SourceApplicationSet { get; set; }
public override int SaveChanges()
{
foreach (var history in ChangeTracker.Entries()
.Where(e => e.Entity is IModificationHistory && (e.State == EntityState.Added ||
e.State == EntityState.Modified))
.Select(e => e.Entity as IModificationHistory))
{
history.DateModified = DateTime.Now;
if (history.DateCreated == DateTime.MinValue)
{
history.DateCreated = DateTime.Now;
}
}
var result = base.SaveChanges();
foreach (var history in ChangeTracker.Entries()
.Where(e => e.Entity is IModificationHistory)
.Select(e => e.Entity as IModificationHistory))
{
history.IsDirty = false;
}
return result;
}
// todo need to sort this issue
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "TODO need to sort this issue")]
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (modelBuilder != null)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Configurations.Add(new SoftphoneUserConfiguration());
modelBuilder.Configurations.Add(new InitialCallConfiguration());
modelBuilder.Configurations.Add(new CallAuditConfiguration());
modelBuilder.Configurations.Add(new SourceApplicationConfiguration());
modelBuilder.Configurations.Add(new RecordingErrorTypeConfiguration());
base.OnModelCreating(modelBuilder);
}
}
}
and seed method: 和种子方法:
protected override void Seed(TelephonyContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Console.WriteLine("running in method Configuration.Seed()");
var allRecordingErrorTypes = new List<RecordingErrorType>();
foreach (RecordingErrorTypeEnumeration errorType in Enum.GetValues(typeof(RecordingErrorTypeEnumeration)))
{
allRecordingErrorTypes.Add(new RecordingErrorType
{
ErrorTypeId = errorType,
Name = Enum.GetName(typeof(RecordingErrorTypeEnumeration), errorType),
Description = errorType.GetDescription()
});
}
context.RecordingErrorTypeSet.AddOrUpdate(allRecordingErrorTypes.ToArray());
var a = new SourceApplication { ApplicationId = 1, ApplicationName = "TelephonyService", IsActive = true, UpdatedBy = "System" };
var b = new SourceApplication { ApplicationId = 2, ApplicationName = "MortgagePayments", IsActive = true, UpdatedBy = "System" };
var c = new SourceApplication { ApplicationId = 3, ApplicationName = "HomeInsurancePayments", IsActive = true, UpdatedBy = "System" };
var d = new SourceApplication { ApplicationId = 4, ApplicationName = "CreditCardPayments", IsActive = true, UpdatedBy = "System" };
context.SourceApplicationSet.AddOrUpdate(app =>
new { app.ApplicationId, app.ApplicationName, app.IsActive, app.UpdatedBy }, a, b, c, d);
}
I was unable to replicate the error. 我无法复制错误。 Here is my code:
这是我的代码:
public class MyContext: DbContext{
public MyContext()
{
Database.SetInitializer(new CreateDatabaseIfNotExists<MyContext>());
}
public DbSet<Product> Products { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public int rating { get; set; }
}
internal sealed class Configuration : DbMigrationsConfiguration<MockApplicationUser.MyContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
var dbMigrator = new DbMigrator(this);
// This is required to detect changes.
var pendingMigrationsExist = dbMigrator.GetPendingMigrations().Any();
if (pendingMigrationsExist)
{
dbMigrator.Update();
}
}
protected override void Seed(MockApplicationUser.MyContext context)
{
Product[] products = new Product[] { new Product { Name = "Product1", rating = 1 }, new Product { Name = "Product1", rating = 1 }, new Product { Name = "Product1", rating = 1 } };
context.Products.AddOrUpdate(products);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.