杨中科 .NETCORE ENTITY FRAMEWORK CORE-1 EFCORE 第一部分

一 、什么是EF Core

什么是ORM

1、说明: 本课程需要你有数据库、SOL等基础知识。
2、ORM: ObjectRelational Mapping。让开发者用对象操作的形式操作关系数据库
比如插入:

User user = new User(Name="admin"Password="123”;
orm.Save(user);

比如查询:

Book b = orm.Books.Single(b=>b.Id==3||b.Name.Contains(".NET"));
string bookName = b.Name;
string aName = b.Author.Name;

3、有哪些ORM: EF core(官方推荐)、Dapper、SqlSugar、FreeSql等

EF Core与其他ORM比较

1、Entity Framework Core(EF Coxe)是微软官方的ORM框架优点: 功能强大、官方支持、生产效率高、力求屏蔽底层数据库差异;
缺点: 复杂、上手门槛高、不熟悉EFCore的话可能会进坑。

2、Dapper。优点: 简单,N分钟即可上手,行为可预期性强;
缺点:生产效率低,需要处理底层数据库差异。

3、EF Core是模型驱动(Model-Driven)的开发思想,Dapper是数据库驱动(DataBase-Driven)的开发思想的。没有优劣,只有比较。

4、性能: Dapper≠性能高; EF Core≠性能差。

5、EF Core是官方推荐、推进的框架,尽量屏蔽底层数据库差异,.NET开发者必须熟悉,根据的项目情况再决定用哪个。

选择

1、个人建议(仅供参考): 对于后台系统、信息系统等和数据库相关开发工作量大的系统,且团队比较稳定,用EF Core;对于互联网系统等数据库相关工作量不大的系统,或者团队不稳定,用Dapper
2、在项目中可以混用,只要注意EF Core的缓存、Tracking等问题即可。

EF Core与EF比较

1、EF有DB First、ModelFirst、Code First。EF Core不支持模型优先,推荐使用代码优先,遗留系统可以使用Scaffold-DbContext来生成代码实现类似DBFirst的效果,但是推荐用Code First .
2、EF会对实体上的标注做校验,EF Core追求轻量化,不校验
3、熟悉EF的话,掌握EFCore会很容易,很多用法都移植过来了。EF Core又增加了很多新东西。
4、EF中的一些类的命名空间以及一些方法的名字在EF Core中稍有不同。
5、EF不再做新特性增加。

搭建 EFCORE 环境

用什么数据库

1、EF Core是对于底层ADO.NET Core的封装,因此ADO.NET Core支持的数据库不一定被EF Core支持。
2、EF Core支持所有主流的数据库,包括MS SQL Server、Oracle、MySQL、PostgreSQL、SQLite等。可以自己实现Provider支持其他数据库。国产数据库支持问题。3、对于SQLServer支持最完美,MySQL、PostgreSQL也不错 (有能解决的小坑) 。这三者是.NET圈中用的最多的三个。本课程主要用SOLServer讲,如果用其他数据库只要改行代码+绕一些小坑即可,大部分代码用法不变。EFCore能尽量屏蔽底层数据库差异。

开发环境搭建

1、经典步骤:建实体类;
建DbContext;
生成数据库;
编写调用EF Core的业务代码。
2、Book.cs

public class Book
{
	public long Id { get; set; )//主键
	public string Title { get; set; )//标题
	public DateTime PubTime { get; set;}//发布日期
	public double Price { get; set;}//单价
}

3、Install-Package Microsoft.EntityFrameworkCore.SqlServer(这个包依赖了efcore的包,所以不需要在单独安装ef的包)

具体实现

  1. 新建Book、Person 类
    在这里插入图片描述
    在这里插入图片描述

  2. 安装程序包
    在这里插入图片描述

开发环境搭建2

创建实现了IEntityTypeConfiguration接口的实体配置类,配置实体类和数据库表的对应关系
Book

class BookEntityConfig:IEntityTypeConfiguration<Book>
{
	public void Configure(EntityTypeBuilder<Book> builder)
	{
		builder.ToTable("T_Books");
	}
	
}

Person

class BookEntityConfig:IEntityTypeConfiguration<Person>
{
	public void Configure(EntityTypeBuilder<Book> builder)
	{
		builder.ToTable("T_Persons");
	}
	
}

浅谈这里的约定大约配置

1.新建BookConfig类 实现 IEntityTypeConfiguration
在这里插入图片描述

列名会根据约定 根据实体类中的数据自动生成

在这里插入图片描述

开发环境搭建3

创建继承自DbContext的类

class TestDbContext:DbContext
{
	// 有哪些实体
	public DbSet<Book> Books { get; set; }
	public DbSet<Book> Persons { get; set; }
	
	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
	{
	//连接数据库
		string connStr ="Server=.;Database=demol;Trusted_Connection=True;MultipleActiveResultSets=true";
		optionsBuilder.UseSqlServer(connStr);
	}
	
	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
	base.OnModelCreating(modelBuilder);
	//从当前程序集加载 上一步中 所有实现 IEntityTypeConfiguration<T>的类
	modelBuilder.ApplyConfigurationsFromAssembly(this.GetType()Assembly);
	}
	
}

概念: Migration数据库迁移

面向对象的ORM开发中,数据库不是程序员手动创建的,而是由Migration工具生成的。关系数据库只是盛放模型数据的一个媒介而已,理想状态下,程序员不用关心数据库的操作。
根据对象的定义变化,自动更新数据库中的表以及表结构的操作,叫做Migration (迁移)迁移可以分为多步 (项目进化) ,也可以回滚。

开发环境搭建4-Migration

为了使用生成数据库的工具,Nuget安装否则MicrosoftEntityFrameworkCore.Tools,
否则执行Add_Migration等命令会如下报错
在这里插入图片描述
在这里插入图片描述

开发环境搭建4-Migration

1、再在“程序包管理器控制台”中执行如下命令Add-Migration InitialCreate(取版本名,方便回滚)
会自动在项目的Migrations文件夹中中生成操作数据库的C#代码。讲解一下生成代码的作用。InitialCreate是什么?
2、代码需要执行后才会应用对数据库的操作。“程序包管理器控制台”中执行Update-database。
3、查看一下数据库,表建好了。

1.在这里插入图片描述
此时项目中多出一个Migrations文件
在这里插入图片描述

打开文件查看

在这里插入图片描述

在这里插入图片描述

此时刷新数据库 发现表已经创建完成
在这里插入图片描述

在这里插入图片描述

开发环境搭建5-修改表结构

1、项目开发中,根据需要,可能会在已有实体中修改、新增、删除表、列等。
2、想要限制Title的最大长度为50,Title字段设置为“不可为空”,并且想增加一个不可为空且最大长度为20的AuthorName(作者名字)属性。
首先在Book实体类中增加一个AuthorName属性
3、修改BookEntityConfig

builder.ToTable("T Books");
builder.Property(e => e.Title).HasMaxLength(50).IsRequired();
builder.Property(e =>e.AuthorName).HasMaxLength(20).IsRequired();

4、执行Add-Migration AddAuthorName ModifvTitle。取名字有意义
5、Update-Database

演示:

新增表字段

1.在person中 新建BirthPlace属性
在这里插入图片描述
2.执行Add-Migration + name
在这里插入图片描述

此时Migrations中新生成一个 …AddBirth文件,除了日期之外,编号更大

在这里插入图片描述
查看文件内容
在这里插入图片描述

3.验证Update-Database 是编译代码之后在执行,故意添加一行错误代码在执行
在这里插入图片描述

运行结果:

在这里插入图片描述

去掉错误代码,在执行

在这里插入图片描述

运行成功 ,查看数据库表

在这里插入图片描述

添加成功。

修改表字段属性

在这里插入图片描述
发现此时该字段,允许为空,且长度限制为最大程度(因为实体类中为String,String 是可以为空得,长度也不知道为多少)。是不合理得设计。

想要限制Title的最大长度为50,Title字段设置为“不可为空”,并(作者名字)属且想增加一个不可为空且最大长度为20的AuthorName性。

1.在Person中添加新列
在这里插入图片描述

2.修改BookConfig文件
在这里插入图片描述

3.新增dog类
在这里插入图片描述
为了和Dbcontext产生关系,必须加入到 MyDbContext配置类中,才能和数据库产生关系
在这里插入图片描述

4.执行
在这里插入图片描述
【警告】
可能会产生数据丢失(原本长度为不限制,现在改为不限制,)

5.继续执行UPdate-Database
在这里插入图片描述
在这里插入图片描述

6.查看数据库
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

EFCORE 增删改查

插入数据

1、只要操作Books属性,就可以向数据库中增加数据,但是通过C#代码修改Books中的数据只是修改了内存中的数据对Books做修改后,需要调用DbContext的异步方法SaveChangesAsync0把修改保存到数据库。也有同步的保存方法SaveChanges0,但是用EF Core都推荐用异步方法
2、EF Core默认会跟踪(Track)实体类对象以及DbSet的改变。
3、演示数据插入

1.在Main函数中
在这里插入图片描述
2.由于myDbContext 继承自DbContext ,
在这里插入图片描述
DbContext实现了 IDisposable
在这里插入图片描述
3.所以需要 使用 using 防止资源泄漏
在这里插入图片描述

4.执行

在这里插入图片描述

数据插入成功

6.多表插入
在这里插入图片描述
运行结果:
在这里插入图片描述
在这里插入图片描述

查询数据

1、DbSet实现了IEnumerable接口,因此可以对DbSet实施Linq操作来进行数据查询。EF Core会把Linq操作转换为SOL语句。面向对象,而不是面向数据库(SQL)
2、ctx.Books.Where(b => b.Price > 80) Book bl = ctx.Books.Single(b => b.Title==“零基础趣学C语言”);
Book b2 = ctx.Books.FirstOrDefault(b=>b.Id==9);
3、可以使用OrderBy操作进行数据的排序IEnumerable books =ctx.Books.OrderByDescending(b => b.Price)

演示:
插入初始化数据
在这里插入图片描述
数据插入成功
在这里插入图片描述
能使用Linq 查询得原因
在这里插入图片描述
实现了IEnemerable 接口
在这里插入图片描述

查询测试:
在这里插入图片描述

运行结果:

在这里插入图片描述

测试二
在这里插入图片描述
运行结果;
在这里插入图片描述

测试三:排序

在这里插入图片描述
测试结果:
在这里插入图片描述
去除 10 一下的

在这里插入图片描述
【查询】不需要SaveChangesAsync

运行结果:

在这里插入图片描述

查询数据2

1、GroupBy也可以

var groups = ctx.Books.GroupBy(b => b.AuthorName)
.Select(g => new { AuthorName = g.Key,
BooksCount = g.Count(), 
MaxPrice = g.Max(b =>b.Price));
foreach(var g in groups){
	Console.WriteLine($"作者名:{g.AuthorName},
	著作数量:{g.BooksCount},
	最贵的价格:g.MaxPrice}");
}

2、大部分Linq操作都能作用于EF Core

示例:
在这里插入图片描述
运行结果:
在这里插入图片描述

修改、删除

1、要对数据进行修改,首先需要把要修改的数据查询出来,然后再对查询出来的对象进行修改,然后再执行SaveChangesAsync0保存修改。
var b = ctx.Books.Single(b=>b.Title==“数学之美”);
b.AuthorName = “Jun Wu”;
await ctx.SaveChangesAsync));
2、删除也是先把要修改的数据查询出来,然后再调用DbSet或者DbContext的Remove方法把对象删除,然后再执行SaveChangesAsync0保存修改。
var b = ctx.Books.Single(b => b.Title ==“数学之美”);
ctx.Remove(b);
//也可以写成
ctx.Books.Remove(b);
await ctx.SaveChangesAsync();

示例:
在这里插入图片描述
运行结果:
在这里插入图片描述
在这里插入图片描述

批量修改、删除

1、目前批量修改、删除多条数据的方法
局限性:性能低:查出来,再一条条Update、Delete,而不能执行Update … where; delete … where;
2、官方目前还没有支持高效的批量Update、Delete,有在后续版本中增加但是目前只是前期意见征询阶段。
3、我实现了一个开源的高效批量修改、删除的开源项目Zack.EFCore.Batch
https://github.com/yangzhongke/Zack.EFCore.Batch

await ctx.DeleteRangeAsync(b => b.Price > n b.AuthorName == “zack yang”);

await ctx.BatchUpdate()
.Set(b => b.Price,b => b.Price + 3)
.Set(b => b.Title,b => s)
.Set(b => b.AuthorName, b=>b.Title.Substring(3,2)+b,AuthorName.ToUpper())
.Set(b > b.PubTime,b => DateTime.Now)
.where(b => b.Id > n ll b.AuthorName.startswith(“Zack”))
.ExecuteAsync0);

示例:
把所有价格大于10的书 都上涨1元
在这里插入图片描述
运行结果:
在这里插入图片描述
通过 SQL SEVER Profiler 查看当前数据库接受的所有sql 语句
在这里插入图片描述
在这里插入图片描述
执行了多次 update 语句
对于数量很大的功能实现,性能很差

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/318103.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机三级(网络技术)一综合题(IP地址计算)

例题一 &#xff08;正常算&#xff09; 计算并填写下表 地址类别 A类地址段是1.0.0.0~127.255.255.255 1~127 B类地址段是128.0.0.0~191.255.255.255 128~191 C类地址段是192.0.0.0~223.255.255.255 192~223 所以41填A 网络地址为主机位全0 根据子网掩码&…

Redis实现分布式会话

Redis实现分布式会话 1 什么是分布式会话 1 这是我么之前学过的注册登录模式 2 如果非常多的人访问&#xff0c;因为单台服务器的访问承受能力是有限的&#xff0c;那么我们就想用多态服务器来承担压力 3 一般通过负载均衡的方式来实现&#xff0c;来分担服务器的压力。 4 负…

【Redis】Redis数据过期策略、数据淘汰策略

数据过期策略 首先&#xff0c;我们要知道Redis的数据过期策略是惰性删除和定期删除结合使用。 面试题&#xff1a; 惰性删除 定期删除 数据淘汰策略 Redis支持8种数据淘汰策略&#xff1a; noeviction&#xff1a;不淘汰任何key&#xff0c;当内存满时&#xff0c;不写入任何…

TCP之三次握手四次挥手与UDP区别

文章目录 1 TCP三次握手四次挥手1.1 数据包说明1.1.1 TCP数据包1.1.2 UDP数据包1.1.3 TCP和UDP差异1.1.4 TCP可靠性传输机制 1.2 三次握手1.2.1 三次握手定义1.2.2 三次握手问题1.2.2.1 问题引入分析1.2.2.2 历史连接1.2.2.3 同步双方初始序列号1.2.2.4 避免资源浪费 1.3 四次挥…

POSTGRESQL中ETL、fdw的平行替换

POSTGRESQL中ETL、fdw的平行替换 01、简介 “ 在我前两次的文章中&#xff0c;说到postgresql对于python的支持&#xff0c;其实很多功能也就可以封装进入的postgresql数据库中去。比如fdw、etl等&#xff0c;本文将以此为叙述点&#xff0c;进行演示展示” 在postgresql数据…

详解矩阵变换:伸缩,旋转,反射和投影

目录 一. 矩阵子空间 二. 矩阵变换 2.1 伸缩矩阵 2.2 旋转矩阵 2.3 反射矩阵 2.4 投影矩阵 2.5 小结 三. 矩阵变换与函数 3.1 原点 3.2 常数倍性质 3.3 加法性质 3.4 小结 四. 空间变换 五. 小结 一. 矩阵子空间 矩阵与向量相乘Ax可以看成子空间的变换。 零空间…

一文搞定,JMeter的三种参数化方式

1、Test Plan 中添加变量 可以在 Test Plan 中设置好添加变量&#xff0c;变量名可以在任意的位置使用&#xff0c;比如说在线程组中直接用${ 变量名 }方式引用&#xff0c;步骤如下&#xff1a; 1&#xff09;设置变量名和变量值 2&#xff09;添加线程组 3&#xff09;添加…

[情商-11]:人际交流的心理架构与需求层次模型

目录 前言&#xff1a; 一、心理架构 1.1 个体生理层 1.2 个体心理层 1.3 点对点人际交流层 1.4 社会网络层 1.5 社会价值层 二、人的需求层次模型 2.1 需求&#xff08;欲望&#xff09;层次模型 2.2 基因与人需求之间的关系 2.3 个体生理需求 2.4 个体的心理需求…

MyBatis源码分析(六):数据源模块

1. 概述 本文&#xff0c;我们来分享 MyBatis 的数据源模块&#xff0c;对应 datasource 包。如下图所示&#xff1a; ​ 在 MyBatis源码分析&#xff08;二&#xff09;&#xff1a;项目结构 中&#xff0c;简单介绍了这个模块如下&#xff1a; 数据源是实际开发中常用的组件…

5 微信小程序

功能开发 5 功能开发概要今日详细1.发布1.1 发布流程的问题1.2 组件&#xff1a;进度条1.3 修改data中的局部数据1.4 发布示例效果前端后端 1.5 闭包 2.获取前10条新闻&#xff08;动态/心情&#xff0c;无需分页&#xff09;3.复杂版4.文章详细页面 各位小伙伴想要博客相关资料…

Java--业务场景:SpringBoot 通过Redis进行IP封禁实现接口防刷

文章目录 前言具体实现步骤1. 定义自定义注解2. 编写拦截器类IpUrlLimitInterceptor3. 在WebConfig类中添加IpUrlLimitInterceptor4. 添加注解到接口上 测试效果参考文章 前言 在实际项目中&#xff0c;有些攻击者会使用自动化工具来频繁刷新接口&#xff0c;造成系统的瞬时吞…

一些前端学习过程的自测练习题

目录 页面设计部分 1 设计一个简单的学院网站首页&#xff1b; 2.按照图示要求完成简单的登录页面 3.完成如下网站设计 4.完成如下网站设计&#xff08;练习页面布局&#xff09; 5 利用下面素材&#xff0c;设计一个满足H5规范的网页&#xff08;移动端页面练习&#xff…

leetcode刷题记录18(2023-08-29)【最短无序连续子数组(单调栈) | 合并二叉树(dfs) | 任务调度器(桶) | 回文子串(二维dp)】

581. 最短无序连续子数组 给你一个整数数组 nums &#xff0c;你需要找出一个 连续子数组 &#xff0c;如果对这个子数组进行升序排序&#xff0c;那么整个数组都会变为升序排序。 请你找出符合题意的 最短 子数组&#xff0c;并输出它的长度。 示例 1&#xff1a; 输入&am…

TensorRT模型优化模型部署(七)--Quantization量化(PTQ and QAT)(二)

系列文章目录 第一章 TensorRT优化部署&#xff08;一&#xff09;–TensorRT和ONNX基础 第二章 TensorRT优化部署&#xff08;二&#xff09;–剖析ONNX架构 第三章 TensorRT优化部署&#xff08;三&#xff09;–ONNX注册算子 第四章 TensorRT模型优化部署&#xff08;四&am…

Java中finally和return的执行顺序

Java中finally和return的执行顺序 try...catch...finally1. finally语句在return语句执行之后return返回之前执行的2. finally块中的return语句会覆盖try块中的return返回3. 如果finally语句中没有return语句覆盖返回值&#xff0c;那么原来的返回值可能因为finally里的修改而改…

进程的状态

进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型 中&#xff0c;进程状态分为三个基本状态&#xff0c;即就绪态&#xff0c;运行态&#xff0c;阻塞态。在五态模型中&#xff0c;进程分为新建态、就绪态&#xff0c;运行态&#x…

【书生·浦语】大模型实战营——第四课笔记

教程链接&#xff1a;https://github.com/InternLM/tutorial/blob/main/xtuner/README.md 视频链接&#xff1a;https://www.bilibili.com/video/BV1yK4y1B75J/?vd_source5d94ee72ede352cb2dfc19e4694f7622 本次视频的内容分为以下四部分&#xff1a; 目录 微调简介 微调会使…

【ArcGIS遇上Python】ArcGIS Python批量筛选多个shp中指定字段值的图斑(以土地利用数据为例)

文章目录 一、案例分析二、提取效果二、代码运行效果三、Python代码四、数据及代码下载一、案例分析 以土地利用数据为例,提取多个shp数据中的旱地。 二、提取效果 原始土地利用数据: 属性表: 提取的旱地:(以图层名称+地类名称命名)

数据结构——排序算法之快速排序

个人主页&#xff1a;日刷百题 系列专栏&#xff1a;〖C/C小游戏〗〖Linux〗〖数据结构〗 〖C语言〗 &#x1f30e;欢迎各位→点赞&#x1f44d;收藏⭐️留言&#x1f4dd; ​ ​ 前言&#xff1a; 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。 基本思想&…

弟12章 1 网络编程

文章目录 网络协议概述 p164TCP协议与UDP协议的区别 p165 网络协议概述 p164 ipv4&#xff1a;十进制点分制 ipv6&#xff1a;十六进制冒号分隔 TCP协议与UDP协议的区别 p165 tcp协议的三次握手&#xff1a;