翼度科技»论坛 编程开发 .net 查看内容

.Net -- EF Core

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
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 版本:
  1. Install-Package MySql.Data.EntityFrameworkCore -Pre
  2. Install-Package Pomelo.EntityFrameworkCore.MySql
  3. Install-Package Microsoft.EntityFrameworkCore.Tools
复制代码
Sql server 版本:
  1. Install-Package Microsoft.EntityFrameworkCore
  2. Install-Package Microsoft.EntityFrameworkCore.SqlServer
  3. Install-Package Microsoft.EntityFrameworkCore.Tools
复制代码
2.在程序包包管理器控制台 中执行以下语句生成 实体类   Scaffold-DbContext指令详情
–mysql 版本:输入如下指令,
  1. Scaffold-DbContext "server=.;userid=tech5_kj;pwd=xxx;port=3306;database=tech5_kj;sslmode=none;" Pomelo.EntityFrameworkCore.MySql -OutputDir Models -Force
  2. 或者
  3. 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 后面是要更新的表名
  1. Scaffold-DbContext -Force "Server=****;User Id=root;Password=****;Database=****" -Provider "Pomelo.EntityFrameworkCore.MySql" -Tables "myTable"
复制代码
–sql server 版本:
  1. Scaffold-DbContext "Data Source=.;Initial Catalog=EFCore_dbfirst;User ID=sa;Password=sa.123" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Force
  2. 或者
  3. 一般用这个就行!!!!
  4. Scaffold-DbContext "Server=.;Database=EFCoreDemo;uid=sa;pwd=123" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
复制代码
通用的命令格式
  1. Scaffold-DbContext "数据库连接字符串" EF组件名(Microsoft.EntityFrameworkCore.SqlServer/Pomelo.EntityFrameworkCore.MySql/等等) -OutputDir 输出文件夹名称
复制代码
参数说明:
  1. -OutputDir *** 实体文件所存放的文件目录
  2. -ContextDir *** DbContext文件存放的目录
  3. -Context *** DbContext文件名
  4. -Schemas *** 需要生成实体数据的数据表所在的模式
  5. -Tables *** 需要生成实体数据的数据表的集合
  6. -DataAnnotations
  7. -UseDatabaseNames 直接使用数据库中的表名和列名(某些版本不支持)
  8. -Force 强制执行,重写已经存在的实体文件
复制代码
 运行成功后,生成如下实体类

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

 
 添加配置文档appsettings.json
  1. {
  2.   "ConnectionStrings": {
  3.     "NpgsqlDbConn_DBFirst": "Server=127.0.0.1;Port=5432;Database=EFCoreDB;User Id=postgres;Password=1;",
  4.     "MysqlDbConn_CodeFirst": "Server=127.0.0.1;Port=3306;Database=EFCoreCode;User Id=root;Password=hirosedb;"
  5.   }
  6. }
复制代码
 调用
nuget 引用以下三个包:
  1. Microsoft.Extensions.Configuration
  2. Microsoft.Extensions.Configuration.FileExtensions
  3. Microsoft.Extensions.Configuration.Json
复制代码
  1. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  2.         {
  3.             if (!optionsBuilder.IsConfigured)
  4.             {
  5.                 IConfiguration config = new ConfigurationBuilder()
  6.                      .SetBasePath(Directory.GetCurrentDirectory())
  7.                      .AddJsonFile("appsettings.json")
  8.                      .Build();
  9.                 string ConnectStr = config.GetConnectionString("NpgsqlDbConn_DBFirst");
  10.                 optionsBuilder.UseNpgsql(ConnectStr);
  11.             }
  12.         }
复制代码
   CodeFirst

CodeFirst使用Mysql,Nuget安装如下包

 
 
 新建实体类:Book、Comment,使用特性实体与数据库对应
  1. using System.ComponentModel.DataAnnotations;
  2. using System.ComponentModel.DataAnnotations.Schema;
  3. namespace EFCore_CodeFirst
  4. {
  5.     [Table("Book")]   //表名
  6.     public class Book
  7.     {
  8.         [Key]    //主键
  9.         [Column("Id")]  //列名
  10.         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]  //主键自增
  11.         public int Id { get; set; }
  12.         [Column("Title")]
  13.         public string? Title { get; set; }
  14.         [Column("Price")]
  15.         public double? Price { get; set; }
  16.         [Column("PubTime")]
  17.         public DateTime? PubTime { get; set; }=DateTime.Now;
  18.         [Column("AuthorName")]
  19.         public string? AuthorName { get; set; }
  20.     }
  21. }
复制代码
  1. [Table("Comment")]
  2.     public class Comment
  3.     {
  4.         [Key]
  5.         [Column("Id")]
  6.         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  7.         public int Id { get; set; }
  8.         [Column("Title")]
  9.         public string? Title { get; set; }
  10.         [Column("CreatedDate")]
  11.         public DateTime CreatedDate { get; set; }=DateTime.Now;
  12.         [Column("CommentStr")]
  13.         public string? CommentStr { get; set; }
  14.     }
复制代码
创建context类,继承DbContext
  1. using Microsoft.EntityFrameworkCore;
  2. using Microsoft.Extensions.Configuration;
  3. namespace EFCore_CodeFirst
  4. {
  5.     public class CodeFContext : DbContext
  6.     {
  7.         //定义实体  EFcore默认追踪
  8.         public DbSet<Book> Books { get; set; } = null!;
  9.         public DbSet<Comment> Comments { get; set; } = null!;
  10.         private string ConnectStr=null!;
  11.         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  12.         {
  13.             if (!optionsBuilder.IsConfigured)
  14.             {
  15.                 IConfiguration config = new ConfigurationBuilder()
  16.                      .SetBasePath(Directory.GetCurrentDirectory())
  17.                      .AddJsonFile("appsettings.json")
  18.                      .Build();
  19.                 ConnectStr = config.GetConnectionString("MysqlDbConn_CodeFirst");
  20.                 optionsBuilder.UseMySql(ConnectStr, ServerVersion.AutoDetect(ConnectStr));
  21.             }
  22.         }
  23.         protected override void OnModelCreating(ModelBuilder modelBuilder)
  24.         {
  25.             base.OnModelCreating(modelBuilder);
  26.         }
  27.     }
  28. }
复制代码
由实体生成数据库,将EFCore_CodeFirst设为启动项目,调用指令add-migration "变量";

 
 
 会生成如下文件

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

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

 
 
 
 EF Core -- 增删改查

先new一个context实例,通过绑定跟踪的DbSet实体,实现数据操作
  1. private CodeFContext codeFContext= new CodeFContext();
复制代码
 查询
  1. private List<Book> _books;
  2.         public List<Book> Books
  3.         {
  4.             get => _books;
  5.             set => SetProperty  (ref _books, value);
  6.         }
  7. //查询Book表所有数据
  8. Books = codeFContext.Books.ToList();
  9. //条件查询,linq操作
  10. Books = codeFContext.Books.Where(x => x.Id > 3).ToList();
复制代码
插入
  1. private async void InsertData()
  2.         {
  3.             var books=new List<Book>() {
  4.                 new Book() { Title ="追风筝的人"},
  5.                 new Book() { Title ="霍乱时期的爱情"}
  6.             };
  7.             //修改DbSet
  8.             codeFContext.Books.AddRange(books);
  9.             //再save更改
  10.             await codeFContext.SaveChangesAsync();
  11.         }
复制代码
更新
  1. private async void UpdateData()
  2.         {
  3.             //需要先查询
  4.             var books = codeFContext.Books.Where(x => x.Title == "追风筝的人");
  5.             //再对查询到的数据进行修改
  6.             foreach (var item in books)
  7.             {
  8.                 item.Title = "放学后";
  9.             }
  10.             //再save更改
  11.             await codeFContext.SaveChangesAsync();
  12.         }
复制代码
删除
  1. private async void DeleteData()
  2.         {
  3.             //先Linq查询
  4.             var books= codeFContext.Books.Where(x => x.Id>5);
  5.             //从实体中删除数据
  6.             codeFContext.Books.RemoveRange(books);
  7.             //再save更改
  8.             await codeFContext.SaveChangesAsync();
  9.         }
复制代码
EF Core -- 批量更新

EF 目前不提供用于执行批量更新的 API.
 使用EFCore.BulkExtensions操作Postgresql

 Bulk相关(一条操作一个事务,均是传入实体)
  1. //查询
  2. List<Student> students =new List<Student>();
  3. await dbFContext.BulkReadAsync(students);
  4. //插入
  5. var students = new List<Student>(){
  6.                 new Student() {Id=1, Name = "AA" ,StuNum="2010"},
  7.                 new Student() {Id=2, Name = "BB" ,StuNum="2011"},
  8.                 new Student() {Id=3, Name = "CC",StuNum="2012" }};
  9.             await dbFContext.BulkInsertAsync(students);
  10. //删除
  11. var stus = dbFContext.Students;
  12.             await dbFContext.BulkDeleteAsync(stus.ToList());
  13. //更新
  14. var stus = dbFContext.Students.ToList();
  15.             foreach (var item in stus)
  16.             {
  17.                 item.Name += "QQQ";
  18.             }
  19.             await dbFContext.BulkUpdateAsync(stus);
复制代码
Batch相关(按条件)
  1. //删除
  2. await dbFContext.Students.Where(x=>x.Name=="BB").BatchDeleteAsync();
  3. //更新(改成新数据)
  4. await dbFContext.Students.Where(x => x.StuNum == "2222").BatchUpdateAsync(new Student() {StuNum="2233" });
  5. //更新(基于原数据)
  6. await dbFContext.Students.Where(x => x.StuNum == "2233").BatchUpdateAsync(x=>new Student() { StuNum =x.StuNum+ "444" });
复制代码
事务
  1. //Bulk相关(一条操作一个事务,均是传入实体)
  2.         //直接使用这些操作时,每个操作都是独立的事务,并且会自动提交。
  3.         //如果我们需要在单个过程中执行多个操作,则应使用显式事务
  4.         public async void TransactionTest()
  5.         {
  6.             using (var transaction= dbFContext.Database.BeginTransaction())
  7.             {
  8.                 try
  9.                 {
  10.                     var students = new List<Student>(){
  11.                      new Student() {Id=6, Name = "DD" ,StuNum="2044"},
  12.                      new Student() {Id=7, Name = "EE" ,StuNum="2055"}};
  13.                     await dbFContext.BulkInsertAsync(students);
  14.                     await dbFContext.Students.Where(x => x.StuNum == "2044").BatchUpdateAsync(new Student() { Name = "DDEEF" });
  15.                     transaction.Commit();
  16.                 }
  17.                 catch (Exception ex )
  18.                 {
  19.                     //using包裹不需要手写rollback,报错会自动回滚
  20.                     Console.WriteLine(ex.Message);
  21.                 }
  22.                
  23.             }
  24.         }
复制代码
使用 Zack.EFCore.Batch.MySQL.Pomelo_NET6 操作Mysql
  1. //添加配置
  2. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  3.         {
  4.             if (!optionsBuilder.IsConfigured)
  5.             {
  6.                 optionsBuilder.UseBatchEF_MySQLPomelo();
  7.             }
  8.         }
  9. //批量删除,
  10. await codeFContext.DeleteRangeAsync<Book>(x=>x.Id>5);
  11. //批量更新,条件,设置更新的列和值,执行
  12.             await codeFContext.BatchUpdate<Book>()
  13.                 .Where(x => x.Title == "放学后")
  14.                 .Set(x=>x.Title,x=>x.Title+"Test")
  15.                 .Set(x=>x.Price,x=>20)
  16.                 .ExecuteAsync();
  17. //批量删除和批量更新都支持通过Take()、Skip()来实现部分删除和部分更新
  18. // Take(3) 代表选取3个 ,如果满足条件的不足3个 那就有几个选几个 可以一个都没有,超过的话只选顺序前 3 个
  19. await codeFContext.Books.Where(x=>x.Id>5).Take(3).DeleteRangeAsync(codeFContext);
  20. //Skip(3) 代表跳过3个 ,如果满足条件的不足3个 那就有几个选几个 跳过几个,超过的话只跳过顺序的前 3 个
  21. await codeFContext.BatchUpdate<Book>()
  22.                 .Where(x => x.Title == "放学后")
  23.                 .Set(x => x.Title, x => x.Title + "Test")
  24.                 .Set(x => x.Price, x => 20)
  25.                 .Skip(3)
  26.                 .ExecuteAsync();
  27. //批量插入
  28. var books=new List<Book>() {
  29.                 new Book() { Title ="追风筝的人"},
  30.                 new Book() { Title ="霍乱时期的爱情"}
  31.             };
  32.             await codeFContext.BulkInsertAsync(books);
复制代码
 
相关链接: https://blog.csdn.net/a549742320/article/details/124094237
                  https://www.cnblogs.com/wl-blog/p/16500751.html
 

来源:https://www.cnblogs.com/Liyuting/archive/2023/03/09/17198407.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具