使用迁移更新代码优先数据库
Posted
技术标签:
【中文标题】使用迁移更新代码优先数据库【英文标题】:Updating a code-first database with migrations 【发布时间】:2018-02-24 11:13:12 【问题描述】:我已经通过this question here 的答案,到目前为止,没有任何提及适用或解决了这个问题。
编辑
我尝试过的:
更新了 __MigrationHistory 表中的 ContextKey 列。 从旧版本的项目中复制了所有旧迁移。问题
我刚刚在我的应用程序中遇到了一个错误,该错误是由应该链接 2 个表的列中的 0 值引起的。因此,我更新了我的数据模型以构建它们之间的关系:
public class ContactGroup
public int Id get; set;
public string Name get; set;
public class Contact
public int Id get; set;
public ContactGroup ContactGroup get; set;
// other contact columns go here
我拥有的其他表之一称为 Campaigns,所以现在添加了一个设置我的外键的迁移,我想update-database
这是我的问题所在,因为我收到一条错误消息:
数据库中已经有一个名为“Campaigns”的对象。
我知道数据库中已经有一个具有此名称的对象,因为它是我正在与之建立关系的对象之一。
这是由实体框架生成的迁移
public partial class StructuredRelationships : DbMigration
public override void Up()
CreateTable(
"dbo.Campaigns",
c => new
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Client = c.String(),
EmailAddress = c.String(),
PhoneNumber = c.String(),
FaxNumber = c.String(),
PhysicalAddress = c.String(),
PostalAddress = c.String(),
DateSent = c.DateTime(),
SmtpServerAddress = c.String(),
SmtpServerPort = c.Int(nullable: false),
SmtpServerUser = c.String(),
SmtpServerPassword = c.String(),
Deleted = c.Boolean(nullable: false),
SendInterval = c.Int(nullable: false),
)
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.ContactGroups",
c => new
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Deleted = c.Boolean(nullable: false),
)
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Contacts",
c => new
Id = c.Int(nullable: false, identity: true),
ContactGroupId = c.Int(nullable: false),
CompanyName = c.String(),
Salutation = c.String(),
FirstName = c.String(),
LastName = c.String(),
EmailAddress = c.String(),
Telephone = c.String(),
DirectTel = c.String(),
Mobile = c.String(),
BroadDesignation = c.String(),
Designation = c.String(),
EmployeeCount = c.Int(nullable: false),
EmployeeCountBand = c.String(),
SaTelProvince = c.String(),
SaBroadArea = c.String(),
Town = c.String(),
Suburb = c.String(),
Type = c.String(),
SpecificBusinessClassification = c.String(),
ReferenceNumber = c.String(),
Deleted = c.Boolean(nullable: false),
)
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.ContactGroups", t => t.ContactGroupId, cascadeDelete: true)
.Index(t => t.ContactGroupId);
CreateTable(
"dbo.Emails",
c => new
Id = c.Int(nullable: false, identity: true),
CampaignId = c.Int(nullable: false),
TemplateId = c.Int(nullable: false),
Sender = c.String(),
From = c.String(),
FromAddress = c.String(),
ReplyTo = c.String(),
ReplyToAddress = c.String(),
Subject = c.String(),
Body = c.String(),
Footer = c.String(),
DateCreated = c.DateTime(nullable: false),
Deleted = c.Boolean(nullable: false),
)
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Campaigns", t => t.CampaignId, cascadeDelete: true)
.Index(t => t.CampaignId);
CreateTable(
"dbo.EmailSends",
c => new
Id = c.Int(nullable: false, identity: true),
CampaignId = c.Int(nullable: false),
EmailId = c.Int(nullable: false),
ContactGroupId = c.Int(nullable: false),
SendDate = c.DateTime(nullable: false),
TotalRecipients = c.Int(nullable: false),
TotalSent = c.Int(nullable: false),
TotalFailed = c.Int(nullable: false),
Status = c.String(),
CompletedDate = c.DateTime(),
Deleted = c.Boolean(nullable: false),
TrackerUrl = c.String(),
)
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Campaigns", t => t.CampaignId, cascadeDelete: true)
.ForeignKey("dbo.ContactGroups", t => t.ContactGroupId, cascadeDelete: true)
.ForeignKey("dbo.Emails", t => t.EmailId, cascadeDelete: true)
.Index(t => t.CampaignId)
.Index(t => t.EmailId)
.Index(t => t.ContactGroupId);
CreateTable(
"dbo.EmailTemplates",
c => new
Id = c.Int(nullable: false, identity: true),
Name = c.String(),
Markup = c.String(),
Deleted = c.Boolean(nullable: false),
)
.PrimaryKey(t => t.Id);
public override void Down()
DropForeignKey("dbo.EmailSends", "EmailId", "dbo.Emails");
DropForeignKey("dbo.EmailSends", "ContactGroupId", "dbo.ContactGroups");
DropForeignKey("dbo.EmailSends", "CampaignId", "dbo.Campaigns");
DropForeignKey("dbo.Emails", "CampaignId", "dbo.Campaigns");
DropForeignKey("dbo.Contacts", "ContactGroupId", "dbo.ContactGroups");
DropIndex("dbo.EmailSends", new[] "ContactGroupId" );
DropIndex("dbo.EmailSends", new[] "EmailId" );
DropIndex("dbo.EmailSends", new[] "CampaignId" );
DropIndex("dbo.Emails", new[] "CampaignId" );
DropIndex("dbo.Contacts", new[] "ContactGroupId" );
DropTable("dbo.EmailTemplates");
DropTable("dbo.EmailSends");
DropTable("dbo.Emails");
DropTable("dbo.Contacts");
DropTable("dbo.ContactGroups");
DropTable("dbo.Campaigns");
那么现在解决此问题并应用此迁移的最佳方法是什么?
【问题讨论】:
【参考方案1】:只需从生成的迁移中删除针对dbo.Campaigns
的CreateTable
方法。对于未来的迁移,这不会被添加,因为模型实际上是在 __MigrationHistory
表中序列化的,并且它知道您已经对其采取了行动。
这会记录在__MigrationHistory
表中的Model
列中,并且它知道Campaigns
已经存在并且不会尝试再次创建它。
希望对你有帮助
【讨论】:
以上是关于使用迁移更新代码优先数据库的主要内容,如果未能解决你的问题,请参考以下文章