ASP.NET Core 入門教程 8、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(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, `hobby` varchar(500) 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")); } 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 - 1)).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 < 0); foreach (UserEntity u in userListFromContext) { u.Age = 0; } var count = DbContext.SaveChanges(); transaction.Commit(); return count; } catch { transaction.Rollback(); return 0; } } } } } } 

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) > 0 ? "success" : "failed"; return Json(new { Message = message, User = user }); } public IActionResult Delete(int id) { var message = Repository.Delete(id) > 0 ? "success" : "failed"; return Json(new { Message = message }); } public IActionResult Update(UserEntity user) { var message = Repository.Update(user) > 0 ? "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 - 1), 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 = 0
                            });
                            var count = command.ExecuteNonQuery();
                            transaction.Commit();
                            return count;
                        }
                        catch (Exception ex)
                        {
                            connection.Close();
                            transaction.Rollback();
                            return 0;
                        }
                    }

                }
            }
        }
    }
}

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) > 0 ? "success" : "failed"; return Json(new { Message = message, User = user }); } public IActionResult Delete(int id) { var message = Repository.Delete(id) > 0 ? "success" : "failed"; return Json(new { Message = message }); } public IActionResult Update(UserEntity user) { var message = Repository.Update(user) > 0 ? "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

五、備注

1、附錄

  • 本文代碼示例

https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-08

  • 本文參考

https://docs.microsoft.com/zh-cn/ef/core
https://www.learnentityframeworkcore.com
https://mysql-net.github.io/MySqlConnector/tutorials/net-core-mvc/



本文首發於我的獨立博客:https://ken.io/note/asp.net-core-tutorial-entity-framework-core-mysql


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM