.Net -- EF Core详解

                               目录                                   

1. EF Core简介

2. Demo运行环境

3. 创建Prism项目 & 类库

4. EF Core -- DBFirst

5. EF Core -- CodeFirst

6. EF Core -- 增删改查

6.1 查询

6.2 插入

6.3 更新

6.4 删除

7. EF Core -- 批量更新

7.1 使用EFCore.BulkExtensions操作Postgresql

7.1.1 Bulk相关(一条操作一个事务,均是传入实体)

7.1.2 Batch相关(按条件)

7.1.3 事务

7.2 使用 Zack.EFCore.Batch.MySQL.Pomelo_NET6 操作Mysql

8. 其他

8.1  VS2022安装PrismTemplatePack

8.2  使用Zack.EFCore.Batch.MySQL.Pomelo_NET6 操作mysql时报错

8.3  插入数据报错

8.4  使用 await dbFContext.BulkReadAsync(students),查询不到数据?

9. github地址

10. 参考


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# 实体类。

2. Demo运行环境

IDE -- VS2022

框架 --  .Net 6.0

数据访问 --  EF Core 6.0.1

UI -- WPF --Prism框架

数据库 -- Mysql、Postgresql

3. 创建Prism项目 & 类库

创建Prism项目,修改目标框架为.Net 6.0

.Net -- EF Core详解_第1张图片

 再创建两个类库,分别对应DBFirst/CodeFirst,为EFCore_Test添加这两个项目引用

 .Net -- EF Core详解_第2张图片

4. EF Core -- DBFirst

使用NuGet安装下图几个包

.Net -- EF Core详解_第3张图片

 DBFirst采用Postgresql。使用pgAdmin 4创建数据库EFCoreDB,三个表student、course、

choose_course

.Net -- EF Core详解_第4张图片

 根据已有数据库生成实体:

将EFCore_DBFirst该项目设置为启动项目,进入程序包控制台,如图:

.Net -- EF Core详解_第5张图片

 输入如下指令,Scaffold-DbContext指令详情

Scaffold-DbContext -Connection "Server=127.0.0.1;Port=5432;Database=EFCoreDB;User Id=postgres;Password=1;" -Provider Npgsql.EntityFrameworkCore.PostgreSQL -Context DBFContext

.Net -- EF Core详解_第6张图片

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

 .Net -- EF Core详解_第7张图片

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

.Net -- EF Core详解_第8张图片

添加配置文档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;"
  }
}

调用

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);
            }
        }

5. EF Core -- CodeFirst

CodeFirst使用Mysql,Nuget安装如下包

.Net -- EF Core详解_第9张图片

 新建实体类: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 Books { get; set; } = null!;
        public DbSet 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详解_第10张图片

会生成如下文件

.Net -- EF Core详解_第11张图片

调用指令Update-Database ,更新数据库.Net -- EF Core详解_第12张图片

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

6. EF Core -- 增删改查

先new一个context实例,通过绑定跟踪的DbSet实体,实现数据操作

private CodeFContext codeFContext= new CodeFContext();

6.1 查询

private List _books;

        public List Books
        {
            get => _books; 
            set => SetProperty  (ref _books, value);
        }
//查询Book表所有数据
Books = codeFContext.Books.ToList();
//条件查询,linq操作
Books = codeFContext.Books.Where(x => x.Id > 3).ToList();

6.2 插入

private async void InsertData()
        {
            var books=new List() { 
                new Book() { Title ="追风筝的人"},
                new Book() { Title ="霍乱时期的爱情"}
            };
            //修改DbSet
            codeFContext.Books.AddRange(books);
            //再save更改
            await codeFContext.SaveChangesAsync();
        }

6.3 更新

private async void UpdateData()
        {
            //需要先查询
            var books = codeFContext.Books.Where(x => x.Title == "追风筝的人");
            //再对查询到的数据进行修改
            foreach (var item in books)
            {
                item.Title = "放学后";
            }
            //再save更改
            await codeFContext.SaveChangesAsync();

        }

6.4 删除

private async void DeleteData()
        {
            //先Linq查询
            var books= codeFContext.Books.Where(x => x.Id>5);
            //从实体中删除数据
            codeFContext.Books.RemoveRange(books);
            //再save更改
            await codeFContext.SaveChangesAsync();
        }

7. EF Core -- 批量更新

EF 目前不提供用于执行批量更新的 API.

7.1 使用EFCore.BulkExtensions操作Postgresql

 7.1.1 Bulk相关(一条操作一个事务,均是传入实体)

//查询
List students =new List();
 await dbFContext.BulkReadAsync(students);
//插入
var students = new List(){
                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);

7.1.2 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" });

7.1.3 事务

//Bulk相关(一条操作一个事务,均是传入实体)
        //直接使用这些操作时,每个操作都是独立的事务,并且会自动提交。
        //如果我们需要在单个过程中执行多个操作,则应使用显式事务
        public async void TransactionTest()
        {
            using (var transaction= dbFContext.Database.BeginTransaction())
            {
                try
                {
                    var students = new List(){
                     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);
                }
                
            }
        }

7.2 使用 Zack.EFCore.Batch.MySQL.Pomelo_NET6 操作Mysql

//添加配置
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseBatchEF_MySQLPomelo();
            }
        }


//批量删除,
await codeFContext.DeleteRangeAsync(x=>x.Id>5);
//批量更新,条件,设置更新的列和值,执行
            await codeFContext.BatchUpdate()
                .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()
                .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() { 
                new Book() { Title ="追风筝的人"},
                new Book() { Title ="霍乱时期的爱情"}
            };
            await codeFContext.BulkInsertAsync(books);

8. 其他

 8.1  VS2022安装PrismTemplatePack

        VS2022扩展中搜不到Prism模板,安装包在github中有。

 8.2  使用Zack.EFCore.Batch.MySQL.Pomelo_NET6 操作mysql时报错

        插入数据   await codeFContext.BulkInsertAsync(books),报如下错误

.Net -- EF Core详解_第13张图片

  解决:在json配置文件中的,连接字符串添加AllowLoadLocalInfile=true

8.3  插入数据报错

 .Net -- EF Core详解_第14张图片

解决:查看全局系统变量 'local_infile' 的值,将其set为on,如下图。自此,插入语句可正常执行

 .Net -- EF Core详解_第15张图片

8.4 使用 await dbFContext.BulkReadAsync(students),查询不到数据?

     求解

9. github地址

KilterW/EFCore_Test: Basic use of EFCore (github.com)

10. 参考

入门 - EF Core | Microsoft Docs

EF Core中高效批量删除、更新数据的Zack.EFCore.Batch发布三个新特性 - 知乎 (zhihu.com)

EFcore使用EFCore.BulkExtensions 批量增加、删除、修改 – MENG (nipoo.net)

        

你可能感兴趣的:(C#,数据库,EF,Core,Zack.EFCore,BulkExtensions,DBFirst,CodeFirst)