伴隨着.net core 技術的成熟,使用.net 開發的項目可以輕松實現跨平台。今天記錄一下 Asp.Net Core MVC + Code First + MySql 的用法,開發工具依然是 Visual Studio(此項目用的是Visual Studio 2019).
1. 創建新項目,選擇Asp.Net Core MVC 模板

2. 填寫項目名稱和解決方案名稱,如下圖所示

解決方案名稱與項目名稱最好有所區別,因為下面還要在該解決方案下添加別的項目(實體類項目以及數據倉促項目等),填寫完成后點擊下一步,如下圖所示

3. 創建項目
點擊創建,Visual Studio開始創建項目。如下圖所示

4. 添加實體類項目(CoreMvc.Entity)
添加類庫項目是為了存放數據實體類,用來生成數據庫中對應的數據表。 右擊解決方案選擇 添加->新項目,如下圖所示

在彈出的添加界面中選擇類庫項目,如下圖所示

點擊下一步,輸入項目名稱(CoreMvc.Entity),如下圖所示

點擊下一步,選擇合適的目標框架(和CoreMvc.Web項目的框架保持一致),如下圖所示

點擊創建,實體類項目創建成功!如下圖所示

5. 添加數據倉儲項目(CoreMvc.Repository)
按照步驟4 添加另外一個類庫項目,並命名 CoreMvc.Repository(創建此項目的目的是為了存放數據庫上下文文件,以及存放項目遷移的紀錄),創建好后如下圖所示

6. CoreMvc.Entity項目下添加實體類
在 CoreMvc.Enity項目下 添加兩個實體類(DepartMent 和 User)以及一個基礎類(EntityBase)代碼如下
using System; using System.ComponentModel.DataAnnotations; namespace CoreMvc.Entity { /// <summary> /// 數據表基類(所有的表都應該繼承該表) /// </summary> public class EntityBase { /// <summary> /// 編號(每張表都應該有ID,並且自動生成,此處使用Guid作為主鍵) /// </summary> [Key] public Guid Id { get; set; } = Guid.NewGuid(); /// <summary> /// 名稱 /// </summary> [Required(ErrorMessage = "名稱是必填項")] public string Name { get; set; } /// <summary> /// 創建時間(默認當前時間) /// </summary> public DateTime CreateTime { get; set; } = DateTime.Now; /// <summary> /// 修改時間(默認當前時間) /// </summary> public DateTime UpdateTime { get; set; } = DateTime.Now; } }
namespace CoreMvc.Entity { /// <summary> /// 部門表 /// </summary> public class Department:EntityBase { /// <summary> /// 部門描述信息 /// </summary> public string Desc { get; set; } /// <summary> /// 部門領導 /// </summary> public string DepartmentLeader { get; set; } /// <summary> /// 部門領導電話 /// </summary> public string LeaderPhone { get; set; } } }
using System; using System.ComponentModel.DataAnnotations.Schema; namespace CoreMvc.Entity { /// <summary> /// 用戶表 /// </summary> public class User:EntityBase { /// <summary> /// 年齡 /// </summary> public int Age { get; set; } /// <summary> /// 性別 /// </summary> public int Sex { get; set; } /// <summary> /// 住址 /// </summary> public string Address { get; set; } /// <summary> /// 部門編號(此字段是外鍵,對應Department表中的Id,對應關系由下面的字段產生) /// </summary> public Guid DepartmentId { get; set; } /// <summary> /// 所屬部門(在生成的數據庫中此字段不顯示,只顯示DepartmentId,其中ForeignKey指向的是上面定義好的DepartmentId字段) /// </summary> [ForeignKey("DepartmentId")] public Department Department { get; set; } } }
7. 在 CoreMvc.Repository項目里 添加NuGet包引用
右擊CoreMvc.Repository項目,選擇 “管理NuGet程序包”如下圖所示

在打開的界面中點擊“瀏覽”選項卡,搜索 Microsoft.EntityFrameworkCore,如下圖所示

由於創建項目時目標框架選擇的是 .Net 5.0,而最新包所依賴的框架是.Net 6.0 因此要降低該包的版本,否則會安裝失敗,更改包的版本后進行安裝,如下圖所示

點擊安裝,則會安裝成功。以同樣的步驟 安裝 Pomelo.EntityFrameworkCore.MySql 和 Microsoft.EntityFrameworkCore.Relational兩個NuGet包
如果出現下圖所示,則表示所依賴的NuGet包已經安裝成功

此處簡單說明一下三個包的作用:
1. Microsoft.EntityFrameworkCore:Entity Framework Core is a lightweight and extensible version of the popular Entity Framework data access technology,提供了數據上下文和DbSet屬性,我們在程序里面就是通過數據上下文和DbSet屬性來對數據庫里面的數據進行操作。
2. Microsoft.EntityFrameworkCore.Relational:Shared Entity Framework Core components for relational database provider:關系數據庫提供者共享EF Core組件。比如我們要將實體映射到數據庫中,都是通過這個包完成的。
3. Pomelo.EntityFrameworkCore.MySql:對於EF Core的Mysql數據庫提供者。假如使用的是Mysql數據庫,那么就需要安裝這個包。對於其他數據庫,EF Core提供的有其相對應的提供程序安裝包。
8. CoreMvc.Repository項目添加CoreMvc.Entity引用
由於CoreMvc.Repository項目需要用到CoreMvc.Entity項目的實體類,因此在該項目下需要添加 CoreMvc.Entity項目的引用,如圖

在彈出的界面上選擇CoreMvc.Entity,如下圖所示

點擊確定按鈕即可。
9. CoreMvc.Repository項目添加數據庫上下文
在CoreMvc.Repository項目里 添加MysqlContext實體類,並繼承DbContext,代碼如下
using CoreMvc.Entity; using Microsoft.EntityFrameworkCore; namespace CoreMvc.Repository { /// <summary> /// 數據上下文 /// </summary> public class MysqlContext : DbContext { public MysqlContext(DbContextOptions<MysqlContext> options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); } /// <summary> /// 部門表(最終生成到數據庫的表名可能會轉為小寫:departments) /// </summary> public DbSet<Department> Departments { get; set; } /// <summary> /// 用戶號表(最終生成到數據庫的表名可能會轉為小寫:users) /// </summary> public DbSet<User> Users { get; set; } } }
10. CoreMvc.Web 項目下 安裝Nuget包
在 CoreMvc.Web項目下需要安裝 Microsoft.EntityFrameworkCore.Tools、Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation兩個Nuget包,安裝步驟參考步驟7,注意對應包的版本的兼容性,安裝成功后如下圖所示

簡單說明一下各個包的用途:
1. Microsoft.EntityFrameworkCore.Tools:Visual Studio中NuGet Package Manager控制台的實體框架核心工具。后續需要需要使用 NuGet Package Manager (程序包管理器控制台)窗口進行數據遷移
2. Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation:調試時,更改cshtml代碼, 刷新瀏覽器可以更新頁面(否則更改了cshtml的代碼時,需要重新啟動項目,瀏覽器才可以更新頁面)
需要在Startup.cs 的ConfigureServices方法中添加 services.AddMvc().AddRazorRuntimeCompilation();
11. CoreMvc.Web 項目下配置數據庫連接字符串
打開appsettings.json文件,添加如下代碼
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ConnectionStrings": { "MyConnectionStr": "Server=localhost;DataBase=CoreMvcTestDB;uid=root;pwd=root123;pooling=true;port=3306;Charset=utf8;sslMode=None;" } }
其中 “MyConnectionStr” 是連接字符串的名稱(可以隨意命名)
"Server=localhost" 指連接本地數據庫(本地需要安裝Mysql數據庫,安裝方法自行百度解決)
“DataBase=CoreMvcTestDB” 指要生成的數據庫名稱(此處做測試使用,實際開發中應該進行有意義的命名)
"uid=root" 指本地數據庫用戶名(安裝mysql數據庫的時候填寫的名字)
“pwd=root123” 指本地mysql數據庫密碼(安裝mysql數據庫的時候設置的密碼)
“pooling=true” 指啟用連接池(連接池是一些與數據庫有關連接的存放地方,當你需要建立某個連接時,如果它已存在與連接池就不需要新建連接了,速度更快,所以建議還是開啟)
"port=3306;" 指數據庫端口(mysql數據庫默認端口是 3306)
“Charset=utf8” 指采用utf8編碼 (為了防止存取數據庫時中文變亂碼或“?”)
"sslMode=None" 使數據庫支持SSL連接
12. CoreMvc.Web項目添加項目引用
由於CoreMvc.Web項目需要用到其它兩個項目,所以需要在該項目下添加項目引用。因為CoreMvc.Repository項目本身就引用了CoreMvc.Entity,所以CoreMvc.Web項目里只需要添加CoreMvc.Repository引用即可, 具體添加方法參考步驟8,添加完成后結果如下圖

13. 配置相關服務
CoreMvc.Web項目下打開Startup.cs文件,添加相關服務配置,最終代碼如下
using CoreMvc.Repository; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace CoreMvc.Web { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext<MysqlContext>(p => p.UseMySql(Configuration.GetConnectionString("MyConnectionStr"), MySqlServerVersion.LatestSupportedServerVersion));//添加數據庫鏈接 services.AddMvc().AddRazorRuntimeCompilation(); //調試時,更改cshtml代碼, 刷新瀏覽器可以更新頁面內容(需要 引入 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 包) services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0).AddJsonOptions(opt => { opt.JsonSerializerOptions.PropertyNamingPolicy = null;//匹配大小寫(否則實體類中的字段傳到View中時全部變成了小寫,比如:Department中的DepartmentLeader字段,傳到View中時變成了 departmentleader) }); services.AddControllersWithViews(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
14. 數據遷移
1. 打開“程序包管理器控制台”
通過 工具-》Nuget包管理器-》程序包管理器控制台 打開“程序包管理器控制台”窗口

2. 設置啟動項目和默認項目

設置啟動項目:因為“包管理器控制台”依賴於包“Microsoft.EntityFrameworkCore.Tools”,此項目中“Microsoft.EntityFrameworkCore.Tools”安裝到了CoreMvc.Web項目下(實際開發中也應該安裝到此項目下,這樣每次遷移數據時就不需要再更換啟動項目),所以啟動項目應該設置為CoreMvc.Web
設置默認項目:“包管理器控制台”中的默認項目指數據上下文(DbContext)所在的項目,因為CoreMvc.Repository項目下的MysqlContext繼承了DbContext,所以默認項目應該設置為 CoreMvc.Repository。
設置完后,遷移數據時,“包管理器控制台”通過“默認項目”找到“MysqlContext”,然后通過 CoreMvc.Repository 項目下的包“Microsoft.EntityFrameworkCore.Relational”將實體類映射到數據庫中。
3. 數據遷移命令
A. 添加遷移命令
在“包管理器控制台中”輸入命令 (命令格式:“Add-Migration 遷移名稱”)
Add-Migration Init
其中“Add-Migration”是固定格式,表示添加遷移,Init是遷移的名稱,可以根據實際需求填寫,此處Init的意思是初始化數據,運行完此命令后,在CoreMvc.Repository項目下會有遷移記錄文件,如下圖所示

B. 更新數據庫命令
輸入“添加遷移”命令后,只是多了遷移記錄文件,數據還沒有更新到數據庫中(首次遷移的時候數據庫還沒有生成,此時可以通過‘Remove-Migration’命令撤回剛才的遷移記錄),如果要將數據更新到數據庫中,需要輸入以下命令
Update-Database
輸入完此命令后,如果出現下圖所示內容,表示數據遷移成功

此時,通過數據庫管理工具(Navicat)查看本地數據庫,則發現“CoreMvcTestDB”數據庫已經生成,如下圖所示

15. 添加控制器
為了實現數據的增刪改查,我們可以在CoreMvc.Web的Controllers文件夾下添加一個空控制器BaseController,用來存放增刪改查的基本代碼,其它控制器可以繼承這個控制器,這樣就可以實現代碼的重用了。代碼如下
using CoreMvc.Entity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic.Core; namespace CoreMvc.Web.Controllers { public class BaseController<D,T> : Controller where D: DbContext where T: EntityBase { /// <summary> /// 鏈接對象 /// </summary> private D _context; public BaseController(D context) { _context = context; } [HttpGet] public virtual JsonResult GetAll(int limit, int offset, string search, string sort, string order, string includes) { var dbSet = _context.Set<T>().OrderBy(d => d.CreateTime).AsQueryable(); #region 查詢 if (!string.IsNullOrEmpty(search)) { dbSet = dbSet.Where(d => d.Name.Contains(search)); } #endregion #region 排序 if (!string.IsNullOrEmpty(sort)) { dbSet = dbSet.OrderBy(string.Format("{0} {1},CreateTime asc", sort, order)); // 根據某個字段排序,需要引入包:System.Linq.Dynamic.Core } #endregion #region Includes 是否包含關聯表的信息 if (!string.IsNullOrEmpty(includes)) { includes.Split(',').ToList().ForEach(i => { dbSet = dbSet.Include(i); }); } #endregion int total = dbSet.Count(); var rows = dbSet.Skip(offset).Take(limit).AsNoTracking().ToList();//AsNoTracking加上之后,對讀取的數據不進行跟蹤,UpdateAsync不會報錯,不然會報 return Json(new { total = total, rows = rows }); } public virtual IActionResult Get(Guid Id, string includes) { var dbSet = _context.Set<T>().AsQueryable(); //自動Includes if (includes != null) { var sp = includes.Split(',').ToList(); sp.ForEach(v => { dbSet = dbSet.Include(v).AsQueryable(); }); } return Ok(dbSet.FirstOrDefault<T>(m => m.Id == Id)); } /// <summary> /// 刪除數據 /// </summary> /// <param name="datas"></param> /// <returns></returns> [HttpPost] public virtual IActionResult Delete(List<T> datas) { try { _context.RemoveRange(datas); _context.SaveChanges(); return Ok(new { status = "success" }); } catch (Exception) { return Ok(new { status = "error" }); } } /// <summary> /// 添加或者修改 /// </summary> /// <param name="t"></param> /// <returns></returns> [HttpPost] public virtual IActionResult Submit([FromForm] T t) { if (!ModelState.IsValid) //判斷驗證是否成功 { string error = ""; foreach (var key in ModelState.Keys) { var modelstate = ModelState[key]; if (modelstate.Errors.Any()) { error = modelstate.Errors.FirstOrDefault().ErrorMessage; } } return Ok(new { status = "error" }); } else { try { var entity = _context.Set<T>().Find(t.Id); //根據Id查詢數據庫中是否存在該記錄 if (entity == null) //不存在則添加 { _context.Add(t); } else { //存在則修改 foreach (var mi in t.GetType().GetProperties()) //遍歷view中傳來的所有字段 { var des = entity.GetType().GetProperty(mi.Name); if (des != null)//如果數據庫中所查詢的記錄包含此字段,則進行賦值修改 { des.SetValue(entity, mi.GetValue(t)); } } _context.Entry<T>(entity).State = EntityState.Modified;//將狀態設置為修改狀態 //_context.Update(t); } _context.SaveChanges(); //保存新增或者修改 return Ok(new { status = "success" }); } catch (Exception error) { return Ok(new { status = "error" }); } } } } }
然后我們再創建一個DepartmentController,讓他繼承BaseController,代碼如下
using CoreMvc.Repository; using Microsoft.AspNetCore.Mvc; namespace CoreMvc.Web.Controllers { public class DepartmentController : BaseController<MysqlContext,Entity.Department> { private MysqlContext _context; public DepartmentController(MysqlContext context):base(context) { _context = context; } public IActionResult Index() { return View(); } } }
數據基本維護的代碼完成后,右擊Index添加視圖,如下圖所示,

點擊添加按鈕,視圖添加成功,此時就可以添加測試數據了。
16. 添加測試數據
該程序數據的顯示以及增刪改查界面使用的是Bootstrap以及BootstrapTable插件。個人比較喜歡bootstrap3,因為它可以更好地兼容bootstraptable插件,但是由於bootstrap版本的不斷升級(目前官方最新版本是5.1.3),所以此處我們采用最新的bootstrap版本。
為了方便使用Table插件,自己封裝了一個table.js。除了這些外還需要toastr.css、toastr.min.js、popup.js等插件,現在不用擔心這些,文章最后提供了源碼下載(最新版本的bootstrap程序源碼和bootstrap3版本的程序源碼),大家可以下載參考。
最終的界面如下圖所示


至此,最簡單的Asp.Net.Core Mvc + Code First + Mysql 項目已經完成。由於本篇章的主要要點是講解項目的架構,所以有關Bootstrap以及BootStraptable等相關的知識會在另外的篇章中講解。現附加源碼下載地址,以供參考。
備注: 源碼使用注意事項
1. 要求本地安裝了 visual studio 2019,框架版本是Net5.0
2. 要求本地安裝了mysql數據庫
3. 下載源碼到本地並解壓(或者通過git直接下載),用Vs2019打開項目
4. 設置CoreMvc.Web為啟動項目
5. 修改CoreMvc.Web項目下的appsettings.json文件中數據庫用戶名和數據庫密碼(安裝mysql時的用戶名和密碼)
6. 在visual studio中打開程序包管理器控制台,設置默認項目為 CoreMvc.Repository
7. “程序包管理器控制台”運行 Add-Migration Init命令
8. "程序包管理器控制台"運行 Update-Database命令
9. 運行項目
