1. EF Core簡介Entity Framework (EF) Core 是輕量化、可擴展、開源和跨平臺版的常用 Entity Framework 數據訪問技術。 EF Core 可用作對象關係映射程式 (O/RM),這可以實現以下兩點: 使 .NET 開發人員能夠使用 .NET 對象處理資料庫 ...
1. EF Core簡介
Entity Framework (EF) Core 是輕量化、可擴展、開源和跨平臺版的常用 Entity Framework 數據訪問技術。
EF Core 可用作對象關係映射程式 (O/RM),這可以實現以下兩點:
使 .NET 開發人員能夠使用 .NET 對象處理資料庫。
無需再像通常那樣編寫大部分數據訪問代碼。
EF Core 支持多個資料庫引擎,請參閱資料庫提供程式瞭解詳細信息。
Code First :先編寫 C# 實體類,EF Core 會根據實體類之間的關係創建資料庫;
Database First :先設計和創建資料庫,EF Core 根據資料庫的表結構生成 C# 實體類。
DBFirst
1.點擊“工具”->“NuGet包管理器”->“程式包管理器控制台”
分別安裝以下幾個包
Mysql 版本:
Install-Package MySql.Data.EntityFrameworkCore -Pre Install-Package Pomelo.EntityFrameworkCore.MySql Install-Package Microsoft.EntityFrameworkCore.Tools
Sql server 版本:
Install-Package Microsoft.EntityFrameworkCore Install-Package Microsoft.EntityFrameworkCore.SqlServer Install-Package Microsoft.EntityFrameworkCore.Tools
2.在程式包包管理器控制台 中執行以下語句生成 實體類 Scaffold-DbContext指令詳情
–mysql 版本:輸入如下指令,
Scaffold-DbContext "server=.;userid=tech5_kj;pwd=xxx;port=3306;database=tech5_kj;sslmode=none;" Pomelo.EntityFrameworkCore.MySql -OutputDir Models -Force 或者 Scaffold-DbContext "server=.;userid=tech5_kj;pwd=xxx;port=3306;database=tech5_kj;sslmode=none;" Pomelo.EntityFrameworkCore.MySql -OutputDir Models -UseDatabaseNames -Force
server:資料庫地址,User Id:賬號,Password:登錄密碼
如果是針對單表的更新,加一個-Tables 後面是要更新的表名
Scaffold-DbContext -Force "Server=****;User Id=root;Password=****;Database=****" -Provider "Pomelo.EntityFrameworkCore.MySql" -Tables "myTable"
–sql server 版本:
Scaffold-DbContext "Data Source=.;Initial Catalog=EFCore_dbfirst;User ID=sa;Password=sa.123" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Force 或者 一般用這個就行!!!! Scaffold-DbContext "Server=.;Database=EFCoreDemo;uid=sa;pwd=123" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
通用的命令格式
Scaffold-DbContext "資料庫連接字元串" EF組件名(Microsoft.EntityFrameworkCore.SqlServer/Pomelo.EntityFrameworkCore.MySql/等等) -OutputDir 輸出文件夾名稱
參數說明:
-OutputDir *** 實體文件所存放的文件目錄 -ContextDir *** DbContext文件存放的目錄 -Context *** DbContext文件名 -Schemas *** 需要生成實體數據的數據表所在的模式 -Tables *** 需要生成實體數據的數據表的集合 -DataAnnotations -UseDatabaseNames 直接使用資料庫中的表名和列名(某些版本不支持) -Force 強制執行,重寫已經存在的實體文件
運行成功後,生成如下實體類
context中配置資料庫連接時,使用明文產生此警告,可改為使用配置文檔
添加配置文檔appsettings.json
{ "ConnectionStrings": { "NpgsqlDbConn_DBFirst": "Server=127.0.0.1;Port=5432;Database=EFCoreDB;User Id=postgres;Password=1;", "MysqlDbConn_CodeFirst": "Server=127.0.0.1;Port=3306;Database=EFCoreCode;User Id=root;Password=hirosedb;" } }
調用
nuget 引用以下三個包:
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.FileExtensions
Microsoft.Extensions.Configuration.Json
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { IConfiguration config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); string ConnectStr = config.GetConnectionString("NpgsqlDbConn_DBFirst"); optionsBuilder.UseNpgsql(ConnectStr); } }
CodeFirst
CodeFirst使用Mysql,Nuget安裝如下包
新建實體類:Book、Comment,使用特性實體與資料庫對應
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EFCore_CodeFirst { [Table("Book")] //表名 public class Book { [Key] //主鍵 [Column("Id")] //列名 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] //主鍵自增 public int Id { get; set; } [Column("Title")] public string? Title { get; set; } [Column("Price")] public double? Price { get; set; } [Column("PubTime")] public DateTime? PubTime { get; set; }=DateTime.Now; [Column("AuthorName")] public string? AuthorName { get; set; } } }
[Table("Comment")] public class Comment { [Key] [Column("Id")] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Column("Title")] public string? Title { get; set; } [Column("CreatedDate")] public DateTime CreatedDate { get; set; }=DateTime.Now; [Column("CommentStr")] public string? CommentStr { get; set; } }
創建context類,繼承DbContext
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace EFCore_CodeFirst { public class CodeFContext : DbContext { //定義實體 EFcore預設追蹤 public DbSet<Book> Books { get; set; } = null!; public DbSet<Comment> Comments { get; set; } = null!; private string ConnectStr=null!; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { IConfiguration config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); ConnectStr = config.GetConnectionString("MysqlDbConn_CodeFirst"); optionsBuilder.UseMySql(ConnectStr, ServerVersion.AutoDetect(ConnectStr)); } } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } } }
由實體生成資料庫,將EFCore_CodeFirst設為啟動項目,調用指令add-migration "變數";
會生成如下文件
調用指令Update-Database ,更新資料庫
使用Navicat查看資料庫,生成成功
EF Core -- 增刪改查
先new一個context實例,通過綁定跟蹤的DbSet實體,實現數據操作
private CodeFContext codeFContext= new CodeFContext();
查詢
private List<Book> _books; public List<Book> Books { get => _books; set => SetProperty (ref _books, value); } //查詢Book表所有數據 Books = codeFContext.Books.ToList(); //條件查詢,linq操作 Books = codeFContext.Books.Where(x => x.Id > 3).ToList();
插入
private async void InsertData() { var books=new List<Book>() { new Book() { Title ="追風箏的人"}, new Book() { Title ="霍亂時期的愛情"} }; //修改DbSet codeFContext.Books.AddRange(books); //再save更改 await codeFContext.SaveChangesAsync(); }
更新
private async void UpdateData() { //需要先查詢 var books = codeFContext.Books.Where(x => x.Title == "追風箏的人"); //再對查詢到的數據進行修改 foreach (var item in books) { item.Title = "放學後"; } //再save更改 await codeFContext.SaveChangesAsync(); }
刪除
private async void DeleteData() { //先Linq查詢 var books= codeFContext.Books.Where(x => x.Id>5); //從實體中刪除數據 codeFContext.Books.RemoveRange(books); //再save更改 await codeFContext.SaveChangesAsync(); }
EF Core -- 批量更新
EF 目前不提供用於執行批量更新的 API.
使用EFCore.BulkExtensions操作Postgresql
Bulk相關(一條操作一個事務,均是傳入實體)
//查詢 List<Student> students =new List<Student>(); await dbFContext.BulkReadAsync(students); //插入 var students = new List<Student>(){ new Student() {Id=1, Name = "AA" ,StuNum="2010"}, new Student() {Id=2, Name = "BB" ,StuNum="2011"}, new Student() {Id=3, Name = "CC",StuNum="2012" }}; await dbFContext.BulkInsertAsync(students); //刪除 var stus = dbFContext.Students; await dbFContext.BulkDeleteAsync(stus.ToList()); //更新 var stus = dbFContext.Students.ToList(); foreach (var item in stus) { item.Name += "QQQ"; } await dbFContext.BulkUpdateAsync(stus);
Batch相關(按條件)
//刪除 await dbFContext.Students.Where(x=>x.Name=="BB").BatchDeleteAsync(); //更新(改成新數據) await dbFContext.Students.Where(x => x.StuNum == "2222").BatchUpdateAsync(new Student() {StuNum="2233" }); //更新(基於原數據) await dbFContext.Students.Where(x => x.StuNum == "2233").BatchUpdateAsync(x=>new Student() { StuNum =x.StuNum+ "444" });
事務
//Bulk相關(一條操作一個事務,均是傳入實體) //直接使用這些操作時,每個操作都是獨立的事務,並且會自動提交。 //如果我們需要在單個過程中執行多個操作,則應使用顯式事務 public async void TransactionTest() { using (var transaction= dbFContext.Database.BeginTransaction()) { try { var students = new List<Student>(){ new Student() {Id=6, Name = "DD" ,StuNum="2044"}, new Student() {Id=7, Name = "EE" ,StuNum="2055"}}; await dbFContext.BulkInsertAsync(students); await dbFContext.Students.Where(x => x.StuNum == "2044").BatchUpdateAsync(new Student() { Name = "DDEEF" }); transaction.Commit(); } catch (Exception ex ) { //using包裹不需要手寫rollback,報錯會自動回滾 Console.WriteLine(ex.Message); } } }
使用 Zack.EFCore.Batch.MySQL.Pomelo_NET6 操作Mysql
//添加配置 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { optionsBuilder.UseBatchEF_MySQLPomelo(); } } //批量刪除, await codeFContext.DeleteRangeAsync<Book>(x=>x.Id>5); //批量更新,條件,設置更新的列和值,執行 await codeFContext.BatchUpdate<Book>() .Where(x => x.Title == "放學後") .Set(x=>x.Title,x=>x.Title+"Test") .Set(x=>x.Price,x=>20) .ExecuteAsync(); //批量刪除和批量更新都支持通過Take()、Skip()來實現部分刪除和部分更新 // Take(3) 代表選取3個 ,如果滿足條件的不足3個 那就有幾個選幾個 可以一個都沒有,超過的話只選順序前 3 個 await codeFContext.Books.Where(x=>x.Id>5).Take(3).DeleteRangeAsync(codeFContext); //Skip(3) 代表跳過3個 ,如果滿足條件的不足3個 那就有幾個選幾個 跳過幾個,超過的話只跳過順序的前 3 個 await codeFContext.BatchUpdate<Book>() .Where(x => x.Title == "放學後") .Set(x => x.Title, x => x.Title + "Test") .Set(x => x.Price, x => 20) .Skip(3) .ExecuteAsync(); //批量插入 var books=new List<Book>() { new Book() { Title ="追風箏的人"}, new Book() { Title ="霍亂時期的愛情"} }; await codeFContext.BulkInsertAsync(books);
相關鏈接: https://blog.csdn.net/a549742320/article/details/124094237
https://www.cnblogs.com/wl-blog/p/16500751.html
如果這篇文章對你有幫助的話,評論或推薦下吧!(轉載請註明原作者!)