日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

ASP.NET?MVC+EF實現(xiàn)異步增刪改查_實用技巧

作者:.NET開發(fā)菜鳥 ? 更新時間: 2022-05-25 編程語言

功能實現(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類型的,方法名稱默認(rèn)以Async結(jié)尾,標(biāo)注為異步方法。

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 Task Details(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()

? @DateTime.Now.Year - 我的 ASP.NET 應(yīng)用程序

@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

欄目分類
最近更新