[英]Code first Entity Framework (EF6) Adding Many-to-Many relationship after initial create
我是MVC,實體框架和數據庫的新手,但我無法弄清楚這里發生了什么。 我試圖通過已經創建的數據庫中的代碼創建多對多關系。 在此先感謝您提供的任何提示。
我有一個由2個模型定義的代碼優先數據庫(實際的數據庫要復雜得多,但為簡潔起見,這也顯示了我的問題)。
public class Beer
{
public int BeerID { get; set; }
public string Name { get; set; }
public virtual ICollection<Company> Companies { get; set; } // one beer could have many companies
}
public class Company
{
public int CompanyID { get; set; }
public string Name { get; set; }
// Navigation Property
}
public class ManyToManyDB : DbContext
{
public DbSet<Beer> Beers { get; set; }
public DbSet<Company> Companies { get; set; }
}
當我運行Enable-Migrations -ContextTypeName ManyToManyTest.Models.ManyToManyDB時,一切都很好。 我在項目中獲得Configuration.cs文件。 我在那里做一些編輯:
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
將一些數據添加到Seed方法中:
context.Companies.AddOrUpdate(c => c.Name,
new Company { Name = "Company1" },
new Company { Name = "Company2" },
new Company { Name = "Company3" }
);
context.Beers.AddOrUpdate(b => b.Name,
new Beer { Name = "Beer1" },
new Beer { Name = "Beer2" },
new Beer { Name = "Beer3" }
);
現在,我運行“ Update-Database -verbose”,並創建了數據庫。 到現在為止還挺好。
現在說我忘了在Company類中創建多對多關系,因此我對其進行了更新:
public class Company
{
public int CompanyID { get; set; }
public string Name { get; set; }
// Navigation Property
public virtual ICollection<Beer> Beers { get; set; } // this is what I forgot, a company can have many beers
}
好的,所以,因為這是開發的早期階段,所以我應該能夠再次運行“ update-database”,它將添加必要的內容(在這種情況下,它將包括一個用於多對多的新聯結表關系)。 不幸的是,當我這樣做時,會發生:
EXECUTE sp_rename @objname = N'dbo.Companies', @newname = N'CompanyBeers', @objtype = N'OBJECT'
警告:更改對象名稱的任何部分都可能會破壞腳本和存儲過程。
IF object_id(N'[dbo].[FK_dbo.Companies_dbo.Beers_Beer_BeerID]', N'F') IS NOT NULL
ALTER TABLE [dbo].[Companies] DROP CONSTRAINT [FK_dbo.Companies_dbo.Beers_Beer_BeerID]
引發此異常
System.Data.SqlClient.SqlException (0x80131904): Cannot find the object "dbo.Companies" because it does not exist or you do not have permissions.
錯誤為:找不到對象“ dbo.Companies”,因為該對象不存在或您沒有權限。
知道為什么在創建初始數據庫模式后無法創建多對多關系嗎?
我可能只是從頭開始嘗試,但是想知道是否有解決方案,以防將來發生這種情況。
如果重要的話,請使用VS2013和EF6.02。 該項目來自普通的MVC模板。
抱歉地說,但這似乎是EF中的錯誤。 EF生成的自動更新與運行“添加遷移”所產生的更新相同。
public override void Up()
{
RenameTable(name: "dbo.Companies", newName: "CompanyBeers");
DropForeignKey("dbo.Companies", "Beer_BeerID", "dbo.Beers");
DropIndex("dbo.Companies", new[] { "Beer_BeerID" });
CreateIndex("dbo.CompanyBeers", "Company_CompanyID");
CreateIndex("dbo.CompanyBeers", "Beer_BeerID");
AddForeignKey("dbo.CompanyBeers", "Company_CompanyID", "dbo.Companies", "CompanyID", cascadeDelete: true);
AddForeignKey("dbo.CompanyBeers", "Beer_BeerID", "dbo.Beers", "BeerID", cascadeDelete: true);
DropColumn("dbo.Companies", "Beer_BeerID");
}
現在,在遷移方法的第二行中,它調用DropForeignKey,它產生帶有DROP的ALTER TABLE並以異常結尾,因為表是首先被重命名的。
解決方法是運行Add-Migration,刪除代碼並手動編寫。 我最終得到了這樣的代碼:
public override void Up()
{
DropIndex("dbo.Companies", new[] { "Beer_BeerID" });
DropForeignKey("dbo.Companies", "Beer_BeerID", "dbo.Beers");
DropColumn("dbo.Companies", "Beer_BeerID");
CreateTable(
"dbo.CompanyBeers",
c => new
{
Company_CompanyID = c.Int(nullable: false),
Beer_BeerID = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.Company_CompanyID, t.Beer_BeerID })
.ForeignKey("dbo.Companies", t => t.Company_CompanyID, cascadeDelete: true)
.ForeignKey("dbo.Beers", t => t.Beer_BeerID, cascadeDelete: true)
.Index(t => t.Company_CompanyID)
.Index(t => t.Beer_BeerID);
}
回答我自己的問題。 經過數小時的思考,就像pg0xC指出的那樣,它可能是實體框架中的錯誤。 如果其他人遇到此問題,這是一個簡單的解決方法。
繼續上面的示例,從Beer和Company類中刪除這兩個ICollection:
public class Beer
{
public int BeerID { get; set; }
public string Name { get; set; }
//public virtual ICollection<Company> Companies { get; set; } // one beer could have many companies
}
public class Company
{
public int CompanyID { get; set; }
public string Name { get; set; }
// Navigation Property
// public virtual ICollection<Beer> Beers { get; set; } // this is what I forgot, a co
}
現在再次運行update-database ...它對示例和實際代碼都有效。 當然,您將失去與啤酒相關的任何公司。 如果這是不可接受的,則您將必須執行與其他應答程序(pg0xC)所述類似的操作。
返回並取消對Beer和Company類中的ICollection的注釋,最后一次運行update-database,一切都應該正常工作。 完成此操作后,我在localdb中有了CompanyBeers聯結表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.