.Net — EF Core

  • .Net — EF Core已关闭评论
  • 241 次浏览
  • A+
所属分类:.NET技术
摘要

1. EF Core简介
Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。

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 强制执行,重写已经存在的实体文件

 运行成功后,生成如下实体类

.Net -- EF Core

 

 context中配置数据库连接时,使用明文产生此警告,可改为使用配置文档

.Net -- EF Core

 

 添加配置文档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安装如下包

.Net -- EF Core

 

 

 新建实体类: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 "变量";

.Net -- EF Core

 

 

 会生成如下文件

.Net -- EF Core

 

 

 调用指令Update-Database ,更新数据库

.Net -- EF Core

 

 

 使用Navicat查看数据库,生成成功

.Net -- EF Core

 

 

 

 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