网站首页 编程语言 正文
目录
- 功能实现
- 1、搭建UI层
- 2、添加实体类
- 3、添加服务接口层
- 4、添加Entity Framework
- 1、开启迁移
- 2、增加迁移
- 3、生成数据库
- 5、添加接口的实现类
- 6、添加控制器
功能实现
我们以学生为例,实现增删改查功能。
1、搭建UI层
我们这里使用ASP.NET MVC作为界面层显示数据,首先创建一个解决方案,然后添加一个MVC项目,命名为TaskAsync.UI,创建后的项目结构如下图所示:

2、添加实体类
我们把实体类放在单独的类库里面,新建一个类型项目,命名为TaskAsync.Model,里面有一个Student类,Student类代码如下:
namespace TaskAsync.Model
{
///
/// 学生类
///
public class Student
{
///
/// 主键
///
public int Id { get; set; }
///
/// 姓名
///
public string Name { get; set; }
///
/// 年龄
///
public int Age { get; set; }
///
/// 性别
///
public int Gender { get; set; }
}
}3、添加服务接口层
我们把增删改查的方法定义在接口里面,新添加一个类型项目,命名为TaskAsync.IService,需要引用上面创建的实体类库。里面有一个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);
///
/// 获取所有数据
///
///
Task> GetAllAsync();
///
/// 根据Id获取单一值
///
///
///
Task GetStudentByIdAsync(int id);
///
/// 更新的异步方法
///
///
///
Task UpdateAsync(Student entity);
}
} 所有的方法返回值都是Task
4、添加Entity Framework
我们使用EF作为ORM框架,把EF放在单独类库里面,命名为TaskAsync.Data。直接在NuGet里面安装:

安装完成以后,我们同样需要在创建的ASP.NET MVC程序里面EntityFramework,然后在外层的Web.config文件里面添加链接字符串:
注意:链接字符串里面的providerName不能省略,否则进行数据迁移的时候会报错。
我们在TaskAsync.Data项目里面添加数据上下文类,继承自父类的DbContext:
using System.Data.Entity;
using TaskAsync.Model;
namespace TaskAsync.Data
{
///
/// 数据上下文类,继承自父类的DbContext
///
public class AppDbContext:DbContext
{
///
/// 通过创建连接,给父类的构造函数传递参数
/// 参数是连接字符串的名称
/// 表示使用连接字符串中名字为DbConnectionString的去连接数据库
///
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; }
}
} 数据上下文类创建完成以后,我们接下来在程序包管理器控制台里面进行数据迁移:

注意:项目要选择EntityFramework所在的类库项目。
1、开启迁移
使用下面的命令开启数据迁移:
Enable-Migrations
命令执行如下图所示:

2、增加迁移
使用下面的命令开始迁移:
Add-Migration Init
命令执行如下图所示:

执行成功以后,会在TaskAsync.Data项目下面添加一个Migrations文件夹

这个文件夹下面有两个类文件:Configuration.cs文件里面是配置信息,另外一个是本次迁移记录文件。我们在Configuration.cs类里面添加一些种子数据:
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、生成数据库
我们在上面配置完成以后,就可以使用下面的命令去生成数据库:
Update-Database
命令执行如下图所示:

命令执行成功,就会自动创建数据库和表,表里面插入我们添加的种子数据:

5、添加接口的实现类
我们添加IStudentService接口的实现类。添加一个单独的类库,命名为TaskAsync.Service,并添加对TaskAsync.Model、TaskAsync.IService、TaskAsync.Data的引用,然后实现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
{
///
/// 新增 方法标注为async
///
///
///
public async Task AddPersonAsync(Student entity)
{
using (AppDbContext dbContext = new AppDbContext())
{
dbContext.Students.Add(entity);
// 调用异步方法
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,数据上下文类选择AppDbContext,如下图所示:

创建完成之后,会看到自动添加了视图:

控制器里也自动生成了代码:
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
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关
// 详细信息,请参阅 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
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关
// 详细信息,请参阅 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
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关
// 详细信息,请参阅 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
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关
// 详细信息,请参阅 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视图文件,添加学生管理的一个标签:
@ViewBag.Title - 我的 ASP.NET 应用程序
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Html.ActionLink("应用程序名称", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
- @Html.ActionLink("主页", "Index", "Home")
- @Html.ActionLink("关于", "About", "Home")
- @Html.ActionLink("联系方式", "Contact", "Home")
- @Html.ActionLink("学生管理", "Index", "Student")
@RenderBody()
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
运行程序,点击“学生管理”标签,就可以看到列表数据了:

这样我们就完成了一个ASP.NET MVC+EF实现异步增删改查的方法了。 最终项目结构:

GitHub代码地址:https://github.com/jxl1024/TaskAsync。
原文链接:https://www.cnblogs.com/dotnet261010/p/12348289.html
相关推荐
- 2022-04-19 运行 npm run xxx 的时候都执行了些什么
- 2022-07-21 React中this指向问题
- 2022-04-12 C语言打印杨辉三角形的示例代码_C 语言
- 2022-11-24 Linux学习之expect操作详解_linux shell
- 2022-07-29 使用React Router v6 添加身份验证的方法_React
- 2023-01-05 Kotlin协程Job生命周期结构化并发详解_Android
- 2022-04-08 Swift使用表格组件实现单列表_Swift
- 2022-10-11 pandas df.sample()的使用_python
- 最近更新
-
- window11 系统安装 yarn
- 超详细win安装深度学习环境2025年最新版(
- Linux 中运行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存储小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基础操作-- 运算符,流程控制 Flo
- 1. Int 和Integer 的区别,Jav
- spring @retryable不生效的一种
- Spring Security之认证信息的处理
- Spring Security之认证过滤器
- Spring Security概述快速入门
- Spring Security之配置体系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置权
- redisson分布式锁中waittime的设
- maven:解决release错误:Artif
- restTemplate使用总结
- Spring Security之安全异常处理
- MybatisPlus优雅实现加密?
- Spring ioc容器与Bean的生命周期。
- 【探索SpringCloud】服务发现-Nac
- Spring Security之基于HttpR
- Redis 底层数据结构-简单动态字符串(SD
- arthas操作spring被代理目标对象命令
- Spring中的单例模式应用详解
- 聊聊消息队列,发送消息的4种方式
- bootspring第三方资源配置管理
- GIT同步修改后的远程分支
