網(wǎng)站首頁 編程語言 正文
功能實現(xiàn)
我們以學(xué)生為例,實現(xiàn)增刪改查功能。
1、搭建UI層
我們這里使用ASP.NET MVC作為界面層顯示數(shù)據(jù),首先創(chuàng)建一個解決方案,然后添加一個MVC項目,命名為TaskAsync.UI,創(chuàng)建后的項目結(jié)構(gòu)如下圖所示:
2、添加實體類
我們把實體類放在單獨的類庫里面,新建一個類型項目,命名為TaskAsync.Model,里面有一個Student類,Student類代碼如下:
namespace TaskAsync.Model { ////// 學(xué)生類 /// public class Student { ////// 主鍵 /// public int Id { get; set; } ////// 姓名 /// public string Name { get; set; } ////// 年齡 /// public int Age { get; set; } ////// 性別 /// public int Gender { get; set; } } }
3、添加服務(wù)接口層
我們把增刪改查的方法定義在接口里面,新添加一個類型項目,命名為TaskAsync.IService,需要引用上面創(chuàng)建的實體類庫。里面有一個IStudentService接口,接口代碼如下:
using System.Collections.Generic; using System.Threading.Tasks; using TaskAsync.Model; namespace TaskAsync.IService { public interface IStudentService { ////// 增加的異步方法 /// /// ///Task AddPersonAsync(Student entity); /// /// 刪除的異步方法 /// /// ///Task DeleteByIdAsync(int id); /// /// 獲取所有數(shù)據(jù) /// ///Task > GetAllAsync(); /// /// 根據(jù)Id獲取單一值 /// /// ///Task GetStudentByIdAsync(int id); /// /// 更新的異步方法 /// /// ///Task UpdateAsync(Student entity); } }
所有的方法返回值都是Task
4、添加Entity Framework
我們使用EF作為ORM框架,把EF放在單獨類庫里面,命名為TaskAsync.Data。直接在NuGet里面安裝:
安裝完成以后,我們同樣需要在創(chuàng)建的ASP.NET MVC程序里面EntityFramework,然后在外層的Web.config文件里面添加鏈接字符串:
注意:鏈接字符串里面的providerName不能省略,否則進(jìn)行數(shù)據(jù)遷移的時候會報錯。
我們在TaskAsync.Data項目里面添加數(shù)據(jù)上下文類,繼承自父類的DbContext:
using System.Data.Entity; using TaskAsync.Model; namespace TaskAsync.Data { ////// 數(shù)據(jù)上下文類,繼承自父類的DbContext /// public class AppDbContext:DbContext { ////// 通過創(chuàng)建連接,給父類的構(gòu)造函數(shù)傳遞參數(shù) /// 參數(shù)是連接字符串的名稱 /// 表示使用連接字符串中名字為DbConnectionString的去連接數(shù)據(jù)庫 /// public AppDbContext():base("name=DbConnectionString") { } ////// 重寫OnModelCreating方法 /// /// protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 配置生成的表名 modelBuilder.Entity().ToTable("T_Student"); base.OnModelCreating(modelBuilder); } public DbSet Students { get; set; } } }
數(shù)據(jù)上下文類創(chuàng)建完成以后,我們接下來在程序包管理器控制臺里面進(jìn)行數(shù)據(jù)遷移:
注意:項目要選擇EntityFramework所在的類庫項目。
1、開啟遷移
使用下面的命令開啟數(shù)據(jù)遷移:
Enable-Migrations
命令執(zhí)行如下圖所示:
2、增加遷移
使用下面的命令開始遷移:
Add-Migration Init
命令執(zhí)行如下圖所示:
執(zhí)行成功以后,會在TaskAsync.Data項目下面添加一個Migrations文件夾
這個文件夾下面有兩個類文件:Configuration.cs文件里面是配置信息,另外一個是本次遷移記錄文件。我們在Configuration.cs類里面添加一些種子數(shù)據(jù):
namespace TaskAsync.Data.Migrations { using System.Collections.Generic; using System.Data.Entity.Migrations; using System.Linq; using TaskAsync.Model; internal sealed class Configuration : DbMigrationsConfiguration{ public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(TaskAsync.Data.AppDbContext context) { List list = new List () { new Student() { Name="Jack", Age=23, Gender=1 }, new Student() { Name="Tom", Age=25, Gender=2 } }; if(!context.Students.Any()) { context.Students.AddRange(list); } } } }
3、生成數(shù)據(jù)庫
我們在上面配置完成以后,就可以使用下面的命令去生成數(shù)據(jù)庫:
Update-Database
命令執(zhí)行如下圖所示:
命令執(zhí)行成功,就會自動創(chuàng)建數(shù)據(jù)庫和表,表里面插入我們添加的種子數(shù)據(jù):
5、添加接口的實現(xiàn)類
我們添加IStudentService接口的實現(xiàn)類。添加一個單獨的類庫,命名為TaskAsync.Service,并添加對TaskAsync.Model、TaskAsync.IService、TaskAsync.Data的引用,然后實現(xiàn)IStudentService接口:
using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TaskAsync.Data; using TaskAsync.IService; using TaskAsync.Model; namespace TaskAsync.Service { public class StudentService : IStudentService { ////// 新增 方法標(biāo)注為async /// /// ///public async Task AddPersonAsync(Student entity) { using (AppDbContext dbContext = new AppDbContext()) { dbContext.Students.Add(entity); // 調(diào)用異步方法 int count = await dbContext.SaveChangesAsync(); return count; } } /// /// 刪除 /// /// ///public async Task DeleteByIdAsync(int id) { using (AppDbContext dbContext = new AppDbContext()) { Student student =await dbContext.Students.FindAsync(new object[] { id }); if(student!=null) { dbContext.Students.Remove(student); return await dbContext.SaveChangesAsync(); } else { return 0; } } } public async Task > GetAllAsync() { List list = await Task.Run >(() => { using (AppDbContext dbContext = new AppDbContext()) { return dbContext.Students.ToList(); } }); return list; } public async Task
GetStudentByIdAsync(int id) { using (AppDbContext dbContext = new AppDbContext()) { Student student = await dbContext.Students.FindAsync(new object[] { id }); if (student != null) { return student } else { return null; } } } public async Task UpdateAsync(Student entity) { using (AppDbContext dbContext = new AppDbContext()) { Student student = await dbContext.Students.FindAsync(new object[] { entity.Id }); if (student != null) { student.Name = entity.Name; student.Age = entity.Age; student.Gender = entity.Gender; dbContext.Entry(student).State = System.Data.Entity.EntityState.Modified; return await dbContext.SaveChangesAsync(); } else { return 0; } } } } }
注意:這里同樣需要添加到EntityFramework的引用。
6、添加控制器
我們在ASP.NET MVC項目里面首先添加對上面幾個類庫的引用。
為了測試方法,我們直接添加一個包含視圖的MVC5控制器(使用Entity Framework),這樣就會自動生成UI界面了,如下圖所示:
模型類選擇Student,數(shù)據(jù)上下文類選擇AppDbContext,如下圖所示:
創(chuàng)建完成之后,會看到自動添加了視圖:
控制器里也自動生成了代碼:
using System.Data.Entity; using System.Linq; using System.Net; using System.Web.Mvc; using TaskAsync.Data; using TaskAsync.Model; namespace TaskAsync.UI.Controllers { public class StudentController : Controller { private AppDbContext db = new AppDbContext(); // GET: Student public ActionResult Index() { return View(db.Students.ToList()); } // GET: Student/Details/5 public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = db.Students.Find(id); if (student == null) { return HttpNotFound(); } return View(student); } // GET: Student/Create public ActionResult Create() { return View(); } // POST: Student/Create // 為了防止“過多發(fā)布”攻擊,請啟用要綁定到的特定屬性,有關(guān) // 詳細(xì)信息,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "Id,Name,Age,Gender")] Student student) { if (ModelState.IsValid) { db.Students.Add(student); db.SaveChanges(); return RedirectToAction("Index"); } return View(student); } // GET: Student/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = db.Students.Find(id); if (student == null) { return HttpNotFound(); } return View(student); } // POST: Student/Edit/5 // 為了防止“過多發(fā)布”攻擊,請啟用要綁定到的特定屬性,有關(guān) // 詳細(xì)信息,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "Id,Name,Age,Gender")] Student student) { if (ModelState.IsValid) { db.Entry(student).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(student); } // GET: Student/Delete/5 public ActionResult Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = db.Students.Find(id); if (student == null) { return HttpNotFound(); } return View(student); } // POST: Student/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Student student = db.Students.Find(id); db.Students.Remove(student); db.SaveChanges(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } }
但是框架生成的代碼都是同步方法的,不是我們需要的,我們改成異步的方法:
using System.Data.Entity; using System.Linq; using System.Net; using System.Threading.Tasks; using System.Web.Mvc; using TaskAsync.Data; using TaskAsync.IService; using TaskAsync.Model; using TaskAsync.Service; namespace TaskAsync.UI.Controllers { public class StudentController : Controller { //private AppDbContext db = new AppDbContext(); IStudentService service = new StudentService(); // GET: Student public async Task Index() { return View(await service.GetAllAsync()); } // GET: Student/Details/5 public async TaskDetails(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student =await service.GetStudentByIdAsync((int)id); if (student == null) { return HttpNotFound(); } return View(student); } // GET: Student/Create public ActionResult Create() { return View(); } // POST: Student/Create // 為了防止“過多發(fā)布”攻擊,請啟用要綁定到的特定屬性,有關(guān) // 詳細(xì)信息,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。 [HttpPost] [ValidateAntiForgeryToken] public async Task Create([Bind(Include = "Id,Name,Age,Gender")] Student student) { if (ModelState.IsValid) { int count = await service.AddPersonAsync(student); if(count>0) { return RedirectToAction("Index"); } } return View(student); } // GET: Student/Edit/5 public async Task Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = await service.GetStudentByIdAsync((int)id); if (student == null) { return HttpNotFound(); } return View(student); } // POST: Student/Edit/5 // 為了防止“過多發(fā)布”攻擊,請啟用要綁定到的特定屬性,有關(guān) // 詳細(xì)信息,請參閱 https://go.microsoft.com/fwlink/?LinkId=317598。 [HttpPost] [ValidateAntiForgeryToken] public async Task Edit([Bind(Include = "Id,Name,Age,Gender")] Student student) { if (ModelState.IsValid) { int count = await service.UpdateAsync(student); if (count > 0) { return RedirectToAction("Index"); } } return View(student); } // GET: Student/Delete/5 public async Task Delete(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Student student = await service.GetStudentByIdAsync((int)id); if (student == null) { return HttpNotFound(); } return View(student); } // POST: Student/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task DeleteConfirmed(int id) { int count = await service.DeleteByIdAsync(id); return RedirectToAction("Index"); } //protected override void Dispose(bool disposing) //{ // if (disposing) // { // db.Dispose(); // } // base.Dispose(disposing); //} } }
然后我們在修改_Layout.cshtml視圖文件,添加學(xué)生管理的一個標(biāo)簽:
@ViewBag.Title - 我的 ASP.NET 應(yīng)用程序 @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr")@RenderBody()@Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false)
運行程序,點擊“學(xué)生管理”標(biāo)簽,就可以看到列表數(shù)據(jù)了:
這樣我們就完成了一個ASP.NET MVC+EF實現(xiàn)異步增刪改查的方法了。 最終項目結(jié)構(gòu):
GitHub代碼地址:https://github.com/jxl1024/TaskAsync。
原文鏈接:https://www.cnblogs.com/dotnet261010/p/12348289.html
相關(guān)推薦
- 2022-04-12 Docker容器部署consul的詳細(xì)步驟_docker
- 2022-12-04 pytorch從頭開始搭建UNet++的過程詳解_相關(guān)技巧
- 2022-08-21 Android用Canvas繪制貝塞爾曲線_Android
- 2023-01-26 Android?源碼淺析RecyclerView?ItemAnimator_Android
- 2022-04-27 關(guān)于AnacondaNavigator?Jupyter?Notebook更換Python內(nèi)核的問題_
- 2023-12-06 Binding to target org.springframework.boot.autocon
- 2022-04-05 h5給input元素type=file的對象賦值報錯
- 2023-04-27 python請求域名requests.(url?=?地址)報錯_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支