ASP.NET Core 入门笔记9,ASP.NET Core + Entity Framework Core 数据访问入门
一、前言
1、本教程主要内容
- ASP.NET Core MVC 集成 EF Core 介绍&操作步骤
- ASP.NET Core MVC 使用 EF Core + Linq to Entity 访问MySQL数据库
- ASP.NET Core MVC 使用 EF Core + 原生SQL访问MySql数据库
- EF Core + MySQL数据库插入数据后获取自增列的值
Entity Framework Core简称为 EF Core
2、本教程环境信息
| 软件/环境 | 说明 |
|---|---|
| 操作系统 | Windows 10 |
| SDK | 2.1.401 |
| ASP.NET Core | 2.1.3 |
| MySQL | 8.0.x |
| IDE | Visual Studio Code 1.30 |
| 浏览器 | Chrome 70 |
| VS Code插件 | 版本 | 说明 |
|---|---|---|
| C# | 1.17.1 | 提供C#智能感知, .NET Core 调试、编译等 |
| vscdoe-solution-explorer | 0.3.1 | 提供解决方案视图 |
本篇代码以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
3、准备工作
安装MySQL数据库:https://dev.mysql.com/downloads/mysql/
- Windows环境
下载安装包后双击安装,一直下一步即可。
- MacOS环境
参考:https://ken.io/note/macos-mysql8-install-config-tutorial
- CentOS环境
参考:https://ken.io/note/centos-mysql8-setup
4、前置知识
- 控制反转(IOC)原则与依赖注入(DI)
ASP.NET Core 默认集成了DI。所有官方模块的引入都要使用DI的方式引入。
https://baike.baidu.com/item/IOC
- Linq使用教程
https://docs.microsoft.com/zh-cn/dotnet/csharp/tutorials/working-with-linq
二、EF Core + MySQL 前置准备
EF Core 全称:Entity Framework Core,为微软为 .NET Core平台开发的ORM框架。对应是 .NET Framework平台的 Entity Framework(EF),无论是EF还是EF Core都可以说是 .NET 平台开发效率最高的ORM框架。
1、引入 EF Core + MySQL Provider
EF Core已经集成在 ASP.NET Core 中,但默认并不支持MySQL,如果需要连接MySQL,需要添加MySQL相关的Provider,这里我选择的是:Pomelo.EntityFrameworkCore.MySql
任意命令行操作即可,我用的是VS Code自带的命令行
//进入项目根目录: Ken.Tutorial.Web
cd Ken.Tutorial.Web
//添加Package
dotnet add package Pomelo.EntityFrameworkCore.MySql
这里我添加的 MySql.Data.EntityFrameworkCore 版本是 8.0.13,如果你想跟我使用一样的版本,可以使用以下命令:
dotnet add package Pomelo.EntityFrameworkCore.MySql --version 2.1.4
2、创建MySQL库表
- 创建数据库
CREATE DATABASE ken_tutorial;
- 创建表
USE ken_tutorial; DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int() NOT NULL AUTO_INCREMENT,
`name` varchar() DEFAULT NULL,
`age` int() DEFAULT NULL,
`hobby` varchar() DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3、配置链接字符串
在项目根目录Ken.Tutorial.Web中创建配置文件appsettings.json,并写入以下配置
{
"ConnectionStrings": {
"testdb": "server=localhost;database=Ken_Tutorial;uid=root;pwd=root;"
}
}
4、实体&DbContext准备
创建user表对应实体
在项目根目录Ken.Tutorial.Web中创建目录Models,并在其中创建类:UserEntity.cs
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace Ken.Tutorial.Web.Models
{
[Table("user")]
[Serializable]
public class UserEntity
{
[Key]//主键
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]//自增列
[Column("id")]
public int Id { get; set; } [Column("name")]
public string Name { get; set; } [Column("age")]
public int Age { get; set; } [Column("hobby")]
public string Hobby { get; set; }
}
}
创建DBContext
在项目根目录Ken.Tutorial.Web中创建目录Repositories,并在其中创建类:TutorialDbContext.cs
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; namespace Ken.Tutorial.Web.Repositories
{
//宏观上我们可以认为这个类就是数据库本身
public class TutorialDbContext : DbContext
{
private IConfiguration Configuration { get; } public TutorialDbContext(IConfiguration configuration)
{
this.Configuration = configuration;
} protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySql(Configuration.GetConnectionString("testdb"));//需要添加引用:MySQL.Data.EntityFrameworkCore
} ppublic DbSet<UserEntity> Users { get; set; }
}
}
TutorialDbContext 继承了 DbContext,然后再Context初始化时配置MySQL链接。
由于 ASP.NET Core 默认使用了DI组件,所以我们取配置文件,就需要在构造函数中获取
IConfiguration注入的实例。
在Startup.cs配置注入,以便数据访问类可以访问DI方式获取TutorialDbContext
public void ConfigureServices(IServiceCollection services)
{
//引入MVC模块
services.AddMvc(); //配置DbContext注入
services.AddTransient<TutorialDbContext>();
}
三、EF Core + Linq to entity 访问数据库
1、创建Linq To Entity 数据访问类
using System;
using System.Collections.Generic;
using System.Linq;
using Ken.Tutorial.Web.Models; namespace Ken.Tutorial.Web.Repositories
{
public class TutorialRepository
{
private TutorialDbContext DbContext { get; } public TutorialRepository(TutorialDbContext dbContext)
{
//在构造函数中注入DbContext
this.DbContext = dbContext;
} //添加
public int Add(UserEntity user)
{
using (DbContext)
{
//由于我们在UserEntity.Id配置了自增列的Attribute,EF执行完成后会自动把自增列的值赋值给user.Id
DbContext.Users.Add(user);
return DbContext.SaveChanges();
} } //删除
public int Delete(int id)
{
using (DbContext)
{
var userFromContext = DbContext.Users.FirstOrDefault(u => u.Id == id);
DbContext.Users.Remove(userFromContext);
return DbContext.SaveChanges();
}
} //更新
public int Update(UserEntity user)
{
using (DbContext)
{
var userFromContext = DbContext.Users.FirstOrDefault(u => u.Id == user.Id);
userFromContext.Name = user.Name;
userFromContext.Age = user.Age;
userFromContext.Hobby = user.Hobby;
return DbContext.SaveChanges();
}
} //查询
public UserEntity QueryById(int id)
{
using (DbContext)
{
return DbContext.Users.FirstOrDefault(u => u.Id == id);
}
} //查询集合
public List<UserEntity> QueryByAge(int age)
{
using (DbContext)
{
return DbContext.Users.Where(u => u.Age == age).ToList();
}
} //查看指定列
public List<string> QueryNameByAge(int age)
{
using (DbContext)
{
return DbContext.Users.Where(u => u.Age == age).Select(u => u.Name).ToList();
}
} //分页查询
public List<UserEntity> QueryUserPaging(int pageSize, int page)
{
using (DbContext)
{
return DbContext.Users.Skip(pageSize * (page - )).Take(pageSize).ToList();
}
} //事务:将年龄<0的用户修改年龄为0
public int FixAge()
{
using (DbContext)
{
using (var transaction = DbContext.Database.BeginTransaction())
{
try
{
var userListFromContext = DbContext.Users.Where(u => u.Age < );
foreach (UserEntity u in userListFromContext)
{
u.Age = ;
}
var count = DbContext.SaveChanges();
transaction.Commit();
return count;
}
catch
{
transaction.Rollback();
return ;
}
}
}
}
}
}
2、创建测试API
在Controllers文件夹下创建EfCoreController.cs作为访问入口
using System;
using Ken.Tutorial.Web.Models;
using Ken.Tutorial.Web.Repositories;
using Microsoft.AspNetCore.Mvc; namespace Ken.Tutorial.Web.Controllers
{
public class EfCoreController : Controller
{
public TutorialRepository Repository { get; } public EfCoreController(TutorialRepository repository)
{
this.Repository = repository;
} public IActionResult Add(UserEntity user)
{
var message = Repository.Add(user) > ? "success" : "failed";
return Json(new { Message = message, User = user });
} public IActionResult Delete(int id)
{
var message = Repository.Delete(id) > ? "success" : "failed";
return Json(new { Message = message });
} public IActionResult Update(UserEntity user)
{
var message = Repository.Update(user) > ? "success" : "failed";
return Json(new { Message = message, User = user });
} public IActionResult QueryById(int id)
{
var user = Repository.QueryById(id);
return Json(new { User = user });
} public IActionResult QueryByAge(int age)
{
var users = Repository.QueryByAge(age);
return Json(new { Users = users });
} public IActionResult QueryNameByAge(int age)
{
var users = Repository.QueryNameByAge(age);
return Json(new { Users = users });
} public IActionResult QueryUserPaging(int pageSize, int page)
{
var users = Repository.QueryUserPaging(pageSize, page);
return Json(new { Users = users });
} public IActionResult FixAge()
{
var count = Repository.FixAge();
return Json(new { FixCount = count });
} }
}
3、启动测试
- 在Startup.cs中配置Repository注入
public void ConfigureServices(IServiceCollection services)
{
//其他代码省略 //配置Repository注入
services.AddTransient<TutorialRepository>();
}
- 启动项目并测试
| API | 示例 |
|---|---|
| 添加用户 | /efcore/add?name=ken&age=18&hobby=coding |
| 删除用户 | /efcore/delete?id=0 |
| 更新用户 | /efcore/update?id=1&name=ken&age=666&hobby=codingOrGaming |
| 查询单个用户 | /efcore/querybyid?id=0 |
| 查询多个用户 | /efcore/querybyage?age=18 |
| 查询多个用户名 | /efcore/querynamebyage?age=18 |
| 分页查询用户 | /efcore/queryuserpaging?pagesize=3&page=1 |
| 修复异常年龄 | /efcore/fixage |
四、EF Core + 原生SQL 访问数据库
1、创建EF Core + 原生SQL 数据访问类
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using Ken.Tutorial.Web.Models;
using Microsoft.EntityFrameworkCore;
using MySql.Data.MySqlClient; namespace Ken.Tutorial.Web.Repositories
{
public class TutorialWithSqlRepository
{
private TutorialDbContext DbContext { get; } public TutorialWithSqlRepository(TutorialDbContext dbContext)
{
//在构造函数中注入DbContext
this.DbContext = dbContext;
} //添加
public int Add(UserEntity user)
{
using (var connection = DbContext.Database.GetDbConnection())
{
connection.Open();
var command = connection.CreateCommand() as MySqlCommand;
command.CommandText = "INSERT INTO user (name,age,hobby) VALUES(@name,@age,@hobby)";
command.Parameters.Add(new MySqlParameter()
{
ParameterName = "@name",
DbType = DbType.String,
Value = user.Name
});
command.Parameters.Add(new MySqlParameter()
{
ParameterName = "@age",
DbType = DbType.Int32,
Value = user.Age
});
command.Parameters.Add(new MySqlParameter()
{
ParameterName = "@hobby",
DbType = DbType.String,
Value = user.Hobby
});
var count = command.ExecuteNonQuery();
//获取插入时产生的自增列Id并赋值给user.Id使用
user.Id = (int)command.LastInsertedId;
return count;
} } //删除
public int Delete(int id)
{
using (DbContext)
{
return DbContext.Database.ExecuteSqlCommand(
"DELETE FROM user WHERE id={0}", id);
}
} //更新
public int Update(UserEntity user)
{
using (DbContext)
{
return DbContext.Database.ExecuteSqlCommand(
"UPDATE user SET name={0}, age={1}, hobby={2} WHERE id={3}",
user.Name, user.Age, user.Hobby, user.Id);
}
} //查询
public UserEntity QueryById(int id)
{
using (DbContext)
{
return DbContext.Users.FromSql("SELECT id,name,age,hobby FROM user WHERE id={0}", id).FirstOrDefault();
}
} //查询集合
public List<UserEntity> QueryByAge(int age)
{
using (DbContext)
{
return DbContext.Users.FromSql("SELECT id,name,age,hobby FROM user WHERE age={0}", age).ToList();
}
} //查看指定列
public List<string> QueryNameByAge(int age)
{
using (DbContext)
{
return DbContext.Users.FromSql("SELECT id,name FROM user WHERE age={0}", age).Select(u => u.Name).ToList();
}
} //分页查询
public List<UserEntity> QueryUserPaging(int pageSize, int page)
{
using (DbContext)
{
return DbContext.Users.FromSql("SELECT id,name,age,hobby FROM user LIMIT {0},{1}", pageSize * (page - ), pageSize).ToList();
}
} //事务:将年龄<0的用户修改年龄为0
public int FixAge()
{
using (DbContext)
{
using (var connection = DbContext.Database.GetDbConnection())
{
//打开连接
connection.Open();
//开启事务
using (var transaction = connection.BeginTransaction())
{
try
{
//获取命令对象
var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = "UPDATE user SET age=@age WHERE age<@age";
command.Parameters.Add(new MySqlParameter()
{
ParameterName = "@age",
DbType = DbType.Int32,
Value =
});
var count = command.ExecuteNonQuery();
transaction.Commit();
return count;
}
catch (Exception ex)
{
connection.Close();
transaction.Rollback();
return ;
}
} }
}
}
}
}
2、创建测试API
在Controllers文件夹下创建EfCoreWithSqlController.cs作为访问入口
using System;
using Ken.Tutorial.Web.Models;
using Ken.Tutorial.Web.Repositories;
using Microsoft.AspNetCore.Mvc; namespace Ken.Tutorial.Web.Controllers
{
public class EfCoreWithSqlController : Controller
{
public TutorialWithSqlRepository Repository { get; } public EfCoreWithSqlController(TutorialWithSqlRepository repository)
{
this.Repository = repository;
} public IActionResult Add(UserEntity user)
{
var message = Repository.Add(user) > ? "success" : "failed";
return Json(new { Message = message, User = user });
} public IActionResult Delete(int id)
{
var message = Repository.Delete(id) > ? "success" : "failed";
return Json(new { Message = message });
} public IActionResult Update(UserEntity user)
{
var message = Repository.Update(user) > ? "success" : "failed";
return Json(new { Message = message, User = user });
} public IActionResult QueryById(int id)
{
var user = Repository.QueryById(id);
return Json(new { User = user });
} public IActionResult QueryByAge(int age)
{
var users = Repository.QueryByAge(age);
return Json(new { Users = users });
} public IActionResult QueryNameByAge(int age)
{
var users = Repository.QueryNameByAge(age);
return Json(new { Users = users });
} public IActionResult QueryUserPaging(int pageSize, int page)
{
var users = Repository.QueryUserPaging(pageSize, page);
return Json(new { Users = users });
} public IActionResult FixAge()
{
var count = Repository.FixAge();
return Json(new { FixCount = count });
} }
}
3、启动测试
- 在Startup.cs中配置Repository注入
public void ConfigureServices(IServiceCollection services)
{
//其他代码省略 //配置Repository注入
services.AddTransient<TutorialWithSqlRepository>();
}
- 启动项目并测试
| API | 示例 |
|---|---|
| 添加用户 | /efcorewithsql/add?name=ken&age=18&hobby=coding |
| 删除用户 | /efcorewithsql/delete?id=0 |
| 更新用户 | /efcorewithsql/update?id=1&name=ken&age=666&hobby=codingOrGaming |
| 查询单个用户 | /efcorewithsql/querybyid?id=0 |
| 查询多个用户 | /efcorewithsql/querybyage?age=18 |
| 查询多个用户名 | /efcorewithsql/querynamebyage?age=18 |
| 分页查询用户 | /efcorewithsql/queryuserpaging?pagesize=3&page=1 |
| 修复异常年龄 | /efcorewithsql/fixage |
本文摘抄自:https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-entity-framework-core-mysql.html
如有侵权,请告知删除或者修改
ASP.NET Core 入门笔记9,ASP.NET Core + Entity Framework Core 数据访问入门的更多相关文章
- Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 更新关系数据
Updating related data¶ 7 of 7 people found this helpful The Contoso University sample web applicatio ...
- Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 读取关系数据
Reading related data¶ 9 of 9 people found this helpful The Contoso University sample web application ...
- Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio »迁移
Migrations¶ 4 of 4 people found this helpful The Contoso University sample web application demonstra ...
- Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 创建复杂数据模型
Creating a complex data model 创建复杂数据模型 8 of 9 people found this helpful The Contoso University sampl ...
- Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 排序、筛选、分页以及分组
Sorting, filtering, paging, and grouping 7 of 8 people found this helpful By Tom Dykstra The Contoso ...
- Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 增、查、改、删操作
Create, Read, Update, and Delete operations¶ 5 of 5 people found this helpful By Tom Dykstra The Con ...
- Working with Data » 使用Visual Studio开发ASP.NET Core MVC and Entity Framework Core初学者教程
原文地址:https://docs.asp.net/en/latest/data/ef-mvc/intro.html The Contoso University sample web applica ...
- Entity Framework Core(EF Core) 最简单的入门示例
目录 概述 基于 .NET Core 的 EF Core 入门 创建新项目 更改当前目录 安装 Entity Framework Core 创建模型 创建数据库 使用模型 基于 ASP.NET Cor ...
- Professional C# 6 and .NET Core 1.0 - 38 Entity Framework Core
本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - 38 Entity Framework ...
- .Net Core 2.0生态(4):Entity Framework Core 2.0 特性介绍和使用指南
前言 这是.Net Core 2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升级EF也发展到EF6.x,Entity Framework Core是一个支持跨平台的全新版本, ...
随机推荐
- 【线段树 dp】8.6集合
线段树维护dp 题目大意 给定初始大小为 $N$ 的正整数集合.定义两个数$x$和$y$建立联系的的代价为 $|x-y|$.我们定义整数集合的代价为:将每个整数都与至少一个另外的整数建立联系之后,所有 ...
- 《深入理解Java虚拟机》之(二、垃圾收集器与内存分配策略)
程序计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭,这几个区域的内存分配和回收都具备确定性,不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟着回收了,而java堆和方法区 ...
- Java实现一行一行读取文件内容(进行编码处理)
// 读取文件内容public String readFile(){ String path = ""; File file = new File(path); StringBui ...
- 长春理工大学第十四届程序设计竞赛D Capture The Flag——哈希&&打表
题目 链接 题意:给定一个字符串 $s$,求不同于 $s$ 的字符串 $t$,使得 $Hash(s) = Hash(t)$,其中 $\displaystyle Hash(s) = \sum_0^{le ...
- JDK、JRE、JVM的区别与关系
JDK JDK是Java开发工具包,是Sun Microsystems针对Java开发员的产品. JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和lib,在这里 ...
- 基于steam的游戏销量预测 — PART 1 — 爬取steam游戏相关数据的爬虫
语言:python 环境:ubuntu 爬取内容:steam游戏标签,评论,以及在 steamspy 爬取对应游戏的销量 使用相关:urllib,lxml,selenium,chrome 解释: 流程 ...
- import org.apache.ibatis.annotations.Param 报错
说明缺少依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus ...
- 数据结构实验之栈与队列一:进制转换(SDUT 2131)
题目链接 题解: 特判一下n==0的时候. #include <bits/stdc++.h> using namespace std; int a[1000]; int main() { ...
- 在linux写一个shell脚本用maven git自动更新代码并且打包部署
服务器上必须安装了git maven jdk 并且配置好环境变量 实际服务器中可能运行着多个Java进程,所以重新部署的时候需要先停止原来的java进程,写一个按照名称杀死进程的脚本 kill.sh ...
- 7.RabbitMQ--消息确认机制(confirm)
RabbitMQ--消息确认机制(confirm) Confirm模式 RabbitMQ为了解决生成者不知道消息是否真正到达broker这个问题,采用通过AMQP协议层面为我们提供了事务机制方案,但是 ...