Asp.net core中Migration工具使用的交流分享
一、文章參數
- 開發工具: - visual studio 2015 community update 3 + .net core tools(preview2) + sqlserver2012 express 
- 開發環境: - win10(版本14393)+ .net core(版本 1.0.0-preview2-003121) 
- 項目名稱: - AirMusic 
- 項目模板: - Asp.net core WebApi(這里不用mvc模板,是因為mvc模板初始的內容太多,這里用不到) 
- AirMusic源碼地址: - https://github.com/boomyao/Blogs 
二、開篇碎語
記得去年第一次做項目,用了asp.net mvc5,因此也第一接觸了EntityFramework(版本是EF6)。 現在打算用asp.net core來完成一個項目,air music是學習asp.net core時新建的demo項目,以后學習core中遇到的一些問題一般會從這個項目產生,今天這篇文章是在migration初始化數據庫時發生的一些問題。
三、主要內容
1、初始化的實體模型
public class Song
? ? {
? ? ? ? public int Id { get; set; }
? ? ? ? [Required]
? ? ? ? public string SongName { get; set; }
? ? ? ? public virtual ICollection<ArtistSong> Artists { get; set; }
? ? ? ? public virtual ICollection<SongListSong> SongLists { get; set; }
? ? }
? ? //歌手
? ? public class Artist
? ? {
? ? ? ? public int Id { get; set; }
? ? ? ? [Required]
? ? ? ? public string Name { get; set; }
? ? ? ? public virtual ICollection<Album> Albums { get; set; }
? ? ? ? public virtual ICollection<ArtistSong> Songs { get; set; }
? ? }
? ? //song with artist n:n table
? ? public class ArtistSong
? ? {
? ? ? ? [Key]
? ? ? ? public int ArtistId { get; set; }
? ? ? ? [Key]
? ? ? ? public int SongId { get; set; }
? ? }
? ? //專輯
? ? public class Album
? ? {
? ? ? ? public int Id { get; set; }
? ? ? ? [Required]
? ? ? ? public string Title { get; set; }
? ? ? ? public virtual ICollection<Song> Songs { get; set; }
? ? }
? ? //歌單
? ? public class SongList
? ? {
? ? ? ? public int Id { get; set; }
? ? ? ? [Required]
? ? ? ? public string Title { get; set; }
? ? ? ? public string Describe { get; set; }
? ? ? ? public virtual ApplicationUser User { get; set; }
? ? ? ? public virtual ICollection<SongListSong> Songs { get; set; }
? ? }
? ? // song with songlist n:n table
? ? public class SongListSong
? ? {
? ? ? ? [Key]
? ? ? ? public int SongListId { get; set; }
? ? ? ? [Key]
? ? ? ? public int SongId { get; set; }
? ? }
Store Models
2、引用EFcoore相關的Nuget包
- "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0" - (依賴了好多ef重要組件) 
- "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final" - (引用了才可以試用migration) 
- "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0" - (我覺得是ef連接sqlserver的必須組件) 
還有就是必須在project.json里的tools節點中添加"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",不然輸入命令”Add Migration“時就會報出下面這句錯誤。
"No parameterless constructor………“這句錯誤是因為ApplicationDbContext(數據庫上下文類)沒有寫下面這個構造函數報的錯誤。
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }?
3、配置數據庫連接
Webapi模板已經創建好了appsetting.json文件,這個文件的作用和web.config是一樣的
?
4、文章包袱:Migration過程中遇到的問題
在ApplicationDbContext重寫的方法OnModelCreating中,有一行代碼
base.OnModelCreating(builder)當我把這行代碼注釋掉時,遷移過程中就會報出如下錯誤:
很明顯,錯誤發生的原因是IdentityUser沒有被映射到ApplicationDbContext,所以可以知道這句代碼的作用,就是用來映射Identity的幾個實體類的,沒有這句,數據庫中就不會自動生成Users、Roles……等Table了,一個讓我很困惑的問題在進行第一次Migration時出現了。AirMusic的實體中,有這樣一種關系:
但是神奇的事情發生了(我不想這樣的):
migrationBuilder.CreateTable(
? ? ? ? ? ? ? ? name: "ArtistSongs",
? ? ? ? ? ? ? ? columns: table => new
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ArtistId = table.Column<int>(nullable: false),
? ? ? ? ? ? ? ? ? ? SongId = table.Column<int>(nullable: false),
? ? ? ? ? ? ? ? ? ? //ArtistId1 = table.Column<int>(nullable: true)
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? constraints: table =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? table.PrimaryKey("PK_ArtistSongs", x => new { x.ArtistId, x.SongId });
? ? ? ? ? ? ? ? ? ? table.ForeignKey(
? ? ? ? ? ? ? ? ? ? ? ? name: "FK_ArtistSongs_Artists_ArtistId",
? ? ? ? ? ? ? ? ? ? ? ? column: x => x.ArtistId,
? ? ? ? ? ? ? ? ? ? ? ? principalTable: "Artists",
? ? ? ? ? ? ? ? ? ? ? ? principalColumn: "Id",
? ? ? ? ? ? ? ? ? ? ? ? onDelete: ReferentialAction.Cascade);
? ? ? ? ? ? ? ? ? ? //table.ForeignKey(
? ? ? ? ? ? ? ? ? ? // ? ?name: "FK_ArtistSongs_Artists_ArtistId1",
? ? ? ? ? ? ? ? ? ? // ? ?column: x => x.ArtistId1,
? ? ? ? ? ? ? ? ? ? // ? ?principalTable: "Artists",
? ? ? ? ? ? ? ? ? ? // ? ?principalColumn: "Id",
? ? ? ? ? ? ? ? ? ? // ? ?onDelete: ReferentialAction.Restrict);
? ? ? ? ? ? ? ? ? ? table.ForeignKey(
? ? ? ? ? ? ? ? ? ? ? ? name: "FK_ArtistSongs_Songs_SongId",
? ? ? ? ? ? ? ? ? ? ? ? column: x => x.SongId,
? ? ? ? ? ? ? ? ? ? ? ? principalTable: "Songs",
? ? ? ? ? ? ? ? ? ? ? ? principalColumn: "Id",
? ? ? ? ? ? ? ? ? ? ? ? onDelete: ReferentialAction.Cascade);
? ? ? ? ? ? ? ? });
? ? ? ? ? ? migrationBuilder.CreateTable(
? ? ? ? ? ? ? ? name: "SongListSongs",
? ? ? ? ? ? ? ? columns: table => new
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? SongListId = table.Column<int>(nullable: false),
? ? ? ? ? ? ? ? ? ? SongId = table.Column<int>(nullable: false),
? ? ? ? ? ? ? ? ? ? //SongListId1 = table.Column<int>(nullable: true)
? ? ? ? ? ? ? ? },
? ? ? ? ? ? ? ? constraints: table =>
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? table.PrimaryKey("PK_SongListSongs", x => new { x.SongListId, x.SongId });
? ? ? ? ? ? ? ? ? ? table.ForeignKey(
? ? ? ? ? ? ? ? ? ? ? ? name: "FK_SongListSongs_Songs_SongId",
? ? ? ? ? ? ? ? ? ? ? ? column: x => x.SongId,
? ? ? ? ? ? ? ? ? ? ? ? principalTable: "Songs",
? ? ? ? ? ? ? ? ? ? ? ? principalColumn: "Id",
? ? ? ? ? ? ? ? ? ? ? ? onDelete: ReferentialAction.Cascade);
? ? ? ? ? ? ? ? ? ? table.ForeignKey(
? ? ? ? ? ? ? ? ? ? ? ? name: "FK_SongListSongs_SongLists_SongListId",
? ? ? ? ? ? ? ? ? ? ? ? column: x => x.SongListId,
? ? ? ? ? ? ? ? ? ? ? ? principalTable: "SongLists",
? ? ? ? ? ? ? ? ? ? ? ? principalColumn: "Id",
? ? ? ? ? ? ? ? ? ? ? ? onDelete: ReferentialAction.Cascade);
? ? ? ? ? ? ? ? ? ? //table.ForeignKey(
? ? ? ? ? ? ? ? ? ? // ? ?name: "FK_SongListSongs_SongLists_SongListId1",
? ? ? ? ? ? ? ? ? ? // ? ?column: x => x.SongListId1,
? ? ? ? ? ? ? ? ? ? // ? ?principalTable: "SongLists",
? ? ? ? ? ? ? ? ? ? // ? ?principalColumn: "Id",
? ? ? ? ? ? ? ? ? ? // ? ?onDelete: ReferentialAction.Restrict);
? ? ? ? ? ? ? ? });
初次Migration中發生意外的代碼(注釋的那些)
自動添加了帶artist1和songlist1的字段,我很希望知道的朋友告訴我解決的辦法!!我實在不知道怎么讓EF不自動添加這個多余的字段,所以我把那些多余的字段都注釋掉后,才update-database到數據庫:
song-artist[N:N] , song-songlist[N:N]
在ApplicationDbContext的OnModelCreating方法里,可以手動的配置數據庫中的關系,像什么組合主鍵啦,組合外鍵啦等等各種約束,都可以 實現。特別是數據庫中實體的關系配置(1:1,1:N,N:N),例如:用方法builder.HasOne().WithMany()就可以建立[1:N]的關系。AirMusic初次Migration中,我也手動的配置了一些關系:
var entityAS=builder.Entity<ArtistSong>();
? ? ? ? ? ? entityAS.HasKey("ArtistId", "SongId");
? ? ? ? ? ? entityAS.HasOne<Artist>()
? ? ? ? ? ? ? ? .WithMany()
? ? ? ? ? ? ? ? .HasForeignKey("ArtistId");
? ? ? ? ? ? var entitySS = builder.Entity<SongListSong>();
? ? ? ? ? ? entitySS.HasKey("SongListId", "SongId");
? ? ? ? ? ? entitySS.HasOne<SongList>()
? ? ? ? ? ? ? ? .WithMany()
? ? ? ? ? ? ? ? .HasForeignKey("SongListId");
上面代碼的作用是,ArtistId和SongId設為ArtistSong的組合主鍵,ArtistSong的ArtistId設為Artist的外鍵。entitySS的作用也大致相同。
四、篇后總結
第一次完整的寫一篇博文,晚上去吃飯是電腦自動重啟更新了,vscode里的代碼都沒保存,打開博客園文章管理發現什么都沒了,難過的就去聽歌睡覺了。第二天起來打算從新來過時,發現有一行“自動保存恢復”,那個感覺就和中了100塊的彩票一樣。
希望有人看完這篇文章吧,新寫手最需要的就是多給建議呀!謝謝
原文地址:http://www.cnblogs.com/boomyao/p/5745525.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的Asp.net core中Migration工具使用的交流分享的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: NSubstitute完全手册索引
- 下一篇: ASP.NET Core依赖注入解读am
