ORM (Object-Relational Mapping)
概念
ORM 是一种程序技术,用于将关系型数据库中的数据映射到对象上。
主要目的是简化数据库操作,使得开发人员可以像操作对象一样来操作数据库。
原理
数据表与类的映射:数据库中的表对应为类。
记录与对象的映射:表中的记录对应为对象实例。
字段与属性的映射:表中的字段对应为类的属性。
优点
提高开发效率:减少 SQL 语句的编写工作。
易于维护:修改数据库结构时,只需调整映射关系,减少对业务逻辑的影响。
增强代码可读性:以面向对象的方式处理数据,更符合编程习惯。
缺点
性能开销:相比直接使用 SQL,ORM 会带来一定的性能损耗。
灵活性降低:对于复杂的查询需求,ORM 可能无法满足或实现起来较为复杂。
核心:以面先对象的思想完成对数据库的操作
常见的ORM
SqlSugar——国内开发者封装设计的
EFCore——EntityFramework Core ——微软提供
Dapper
Dos Orm
。。。。。。
SqlSugar:集其他ORM框架优点于一身;足够简单,满足更多的使用场景
SqlSugar框架
SqlSugar 是一款 老牌 .NET开源ORM框架,由果糖大数据科技团队维护和更新 ,开箱即用最易上手的ORM
优点
【生态丰富】【高性能】【超简单】 【功能全面】 【多库兼容】【适合产品】
支持
.net framework .net core3.1 .ne5 .net6 .net7 .net8 .net9
特色
拥有全球最活跃的ORM线上论坛,比EF还要活跃,交流群人数已超过万人 ,技术支持快,口碑好。
开源
10年开源信誉值得信赖,从不搞收费,文档也全免费
官网
SqlSugar .Net ORM 5.X 官网 、文档、教程 - SqlSugar 5x - .NET果糖网 (donet5.com)
使用步骤
1、新建项目
新建一个控制台项目做测试和一个类库Models
2、Nuget引入SqlSugarCore程序集(不要引错了!)
引入图片中的程序集
引入后结果
3、连接数据库ConnectionConfig🚩进行配置
代码
// See https://aka.ms/new-console-template for more informationusing SqlSugar;Console.WriteLine("Hello, World!");
try
{//1、Nuget 引入程序集//2、通过SqlSugarClient 对象可以完成各种操作。注意选中SqlSugarClient点击F12可以查看源代码ConnectionConfig connectionConfig = new ConnectionConfig(){//DbType = DbType.SqlServer,//ConnectionString = "Data Source=.;Initial Catalog=RotatingWarehouseSystem;User ID=sa;Password=sa123456",ConnectionString = "Server=localhost;Database=net-vue;User ID=root;Password=root123;",DbType = DbType.MySql,InitKeyType = InitKeyType.Attribute};}
catch (Exception e)
{Console.WriteLine( e.Message);throw;
}
4、基于数据库生成实体对象--DbFirst🚩
代码
//1、Nuget 引入程序集//2、通过SqlSugarClient 对象可以完成各种操作。注意选中SqlSugarClient点击F12可以查看源代码ConnectionConfig connectionConfig = new ConnectionConfig(){ConnectionString = "Server=localhost;Database=net-vue;User ID=root;Password=root123;",DbType = DbType.MySql,InitKeyType = InitKeyType.Attribute,IsAutoCloseConnection = true//自动释放};using (SqlSugarClient db=new SqlSugarClient(connectionConfig)){//1、基于数据库生成实体对象--DbFirst//models的路径:F:\PracticeSqlSugar\PracticeSqlSugar\Models{//生成数据库全部的表db.DbFirst.IsCreateAttribute()//创建sqlsugar自带特性.CreateClassFile(@"F:\PracticeSqlSugar\PracticeSqlSugar\Models");}//{// //条件筛选,生成实体(生成什么名字开头的)// db.DbFirst.Where(c=>c.StartsWith("sys_user")).CreateClassFile(@"F:\PracticeSqlSugar\PracticeSqlSugar\Models");//}}
生成结果
sys_user.cs文件内容
using System;
using System.Linq;
using System.Text;namespace Models
{///<summary>///用户信息表///</summary>public partial class sys_user{public sys_user(){}/// <summary>/// Desc:用户ID/// Default:/// Nullable:False/// </summary> public long userId {get;set;}/// <summary>/// Desc:部门ID/// Default:/// Nullable:True/// </summary> public long? deptId {get;set;}/// <summary>/// Desc:用户账号/// Default:/// Nullable:False/// </summary> public string userName {get;set;}/// <summary>/// Desc:用户昵称/// Default:/// Nullable:False/// </summary> public string nickName {get;set;}/// <summary>/// Desc:用户类型(00系统用户)/// Default:0/// Nullable:True/// </summary> public string userType {get;set;}/// <summary>/// Desc:用户邮箱/// Default:/// Nullable:True/// </summary> public string email {get;set;}/// <summary>/// Desc:手机号码/// Default:/// Nullable:True/// </summary> public string phonenumber {get;set;}/// <summary>/// Desc:用户性别(0男 1女 2未知)/// Default:0/// Nullable:True/// </summary> public int? sex {get;set;}/// <summary>/// Desc:头像地址/// Default:/// Nullable:True/// </summary> public string avatar {get;set;}/// <summary>/// Desc:密码/// Default:/// Nullable:True/// </summary> public string password {get;set;}/// <summary>/// Desc:帐号状态(0正常 1停用)/// Default:0/// Nullable:True/// </summary> public int? status {get;set;}/// <summary>/// Desc:删除标志(0代表存在 2代表删除)/// Default:0/// Nullable:True/// </summary> public int? delFlag {get;set;}/// <summary>/// Desc:最后登录IP/// Default:/// Nullable:True/// </summary> public string loginIP {get;set;}/// <summary>/// Desc:最后登录时间/// Default:/// Nullable:True/// </summary> public DateTime? loginDate {get;set;}/// <summary>/// Desc:创建者/// Default:/// Nullable:True/// </summary> public string create_by {get;set;}/// <summary>/// Desc:创建时间/// Default:/// Nullable:True/// </summary> public DateTime? create_time {get;set;}/// <summary>/// Desc:更新者/// Default:/// Nullable:True/// </summary> public string update_by {get;set;}/// <summary>/// Desc:更新时间/// Default:/// Nullable:True/// </summary> public DateTime? update_time {get;set;}/// <summary>/// Desc:备注/// Default:/// Nullable:True/// </summary> public string remark {get;set;}/// <summary>/// Desc:所在省/// Default:/// Nullable:True/// </summary> public string province {get;set;}/// <summary>/// Desc:所在市/// Default:/// Nullable:True/// </summary> public string city {get;set;}}
}
实体配置-配置SugarColumn属性
在 SqlSugar 中,SugarColumn 属性用于配置列的元数据信息,这对于 ORM 映射非常重要。下面是一些常见的 SugarColumn 属性及其用途:
4.1🌟 ColumnName-指定数据库表中对应的列名。
4.2🌟 IsNullable-指定列是否可以为 NULL。
4.3🌟 IsIdentity-指定列是否为自增列。
4.4🌟 IsPrimaryKey-指定列是否为主键。
4.5🌟 DbType-指定列的数据类型。
4.6🌟 Length-指定列的最大长度。
4.7🌟 CSharpType-指定 C# 中的类型
4.8🌟 IsIgnore-指定是否忽略此属性
4.9🌟 Insertable-指定插入时是否包含此列。
4.10🌟 Updatable-指定更新时是否包含此列。
4.11🌟 DefaultValue-指定默认值
示例
public class User
{[SugarColumn(IsIdentity = true, IsPrimaryKey = true, ColumnName = "user_id")]public int UserId { get; set; }[SugarColumn(Length = 50)]public string Name { get; set; }[SugarColumn(Length = 100)]public string Email { get; set; }[SugarColumn(DbType = "datetime")]public DateTime CreatedAt { get; set; }[SugarColumn(DbType = "datetime")]public DateTime UpdatedAt { get; set; }
}
5、完成对数据库的常用操作(增删改查)
①新增表数据-Insertable🚩
支持单条插入和批量插入
单条插入:
代码
// See https://aka.ms/new-console-template for more informationusing Models;
using SqlSugar;Console.WriteLine("Hello, World!");
try
{//1、Nuget 引入程序集//2、通过SqlSugarClient 对象可以完成各种操作。注意选中SqlSugarClient点击F12可以查看源代码ConnectionConfig connectionConfig = new ConnectionConfig(){ConnectionString = "Server=localhost;Database=net-vue;User ID=root;Password=root123;",DbType = DbType.MySql,InitKeyType = InitKeyType.Attribute};using (SqlSugarClient db=new SqlSugarClient(connectionConfig)){//操作表//3、新增表数据var addmodel = new sys_user(){userId = 4,deptId = 0,userName = "111",nickName = "测试SqlSugar",userType = "0",sex = 2,password = "1111",status = 0,};//常用三种,按需使用//正常的db.Insertable<sys_user>(addmodel).ExecuteCommand();//异步await db.Insertable(addmodel).ExecuteCommandAsync();//插入返回自增列 (实体除ORACLE外实体要配置自增,Oracle需要配置序列)db.Insertable(insertObj).ExecuteReturnIdentity();}}
catch (Exception e)
{Console.WriteLine( e.Message);throw;
}
结果
批量插入语法--copy的官网
还有从一个表导入另一个表(不同实体插入和同实体不同表插入,详见官网)
//(1)、非参数化插入(防注入)
//优点:综合性能比较平均,列少1万条也不慢,属于万金油写法,不加事务情况下部分库有失败回滚机质
//缺点:数据量超过5万以上占用内存会比较大些,内存小可以用下面2种方式处理
db.Insertable(List<实体>).ExecuteCommand()
db.Insertable(List<实体>).PageSize(1000).ExecuteCommand() //新功能:分页插入 5.1.4.103+
//(2)、参数化内部分页插入(底层是分页插入)
//优点:适合插入条数固定,并且条数较少,请求频繁高的功能(最大利用执行计划缓存)
//缺点:个别库500以上就开始慢了,要加事务才能回滚
db.Insertable(List<实体>).UseParameter().ExecuteCommand()//5.0.3.8及以上
//(3)、大数据写入(特色功能:大数据处理上比所有框架都要快30%)
//优点:1000条以上性能无敌手
//缺点:不支持数据库默认值, API功能简单, 小数据量并发执行不如普通插入,插入数据越大越适合用这个
//新功能 5.0.44
db.Fastest<实体>().PageSize(100000).BulkCopy(List<实体>);//MySql连接字符串要加AllowLoadLocalInfile=true
②修改表数据-Updateable🚩
细节参考官网:单表更新、更新数据 - SqlSugar 5x - .NET果糖网 (donet5.com)
代码
sys_user user = db.Queryable<sys_user>().OrderBy(c => c.userId, OrderByType.Desc).First();user.sex = 1;db.Updateable<sys_user>(user).ExecuteCommand();
结果
③删除表数据-Deleteable🚩
细节参考官网:普通删除 、单表删除、表达式删除 用法 - SqlSugar 5x - .NET果糖网 (donet5.com)
代码
sys_user user = db.Queryable<sys_user>().OrderBy(c => c.userId, OrderByType.Desc).First();//删除db.Deleteable<sys_user>(user).ExecuteCommand();
结果
④查询表数据-常用的Queryable🚩
🌟查所有
List<sys_user> users = db.Queryable<sys_user>().ToList();//查所有
//select * from sys_user
🌟查总数——Count()
int count =db.Queryable<sys_user>().Count();//查总数//select count(1) from sys_user
🌟条件查询——where(条件)
List<sys_user> user = db.Queryable<sys_user>().Where(it => it.sex == 1).ToList();//条件查询//select * from sys_user where sex = 1
🌟多条件查询——where(条件1&&条件2)
List<sys_user> user = db.Queryable<sys_user>().Where(it => it.userId == 1&&it.sex==1).ToList();//多条件查询//select * from sys_user where userId = 1 and sex = 1
🌟模糊查询——Where(条件+Contains)
db.Queryable<sys_user>().Where(it => it.avatar.Contains("a")).ToList();//模糊查询
//select * from sys_user where avatar like %a%
🌟查满足条件的首条——First(条件)
sys_user user = db.Queryable<sys_user>().First(it => it.sex == 1);//查询满足条件第一条//select top 1 * from sys_user where sex = 1
🌟查满足条件的最后一条——逆序+First(条件)
db.Queryable<sys_user>()
.OrderBy(it=>it.Id,OrderByType.Desc )// 倒序
.First(it => it.sex == 1) //没有返回Null
//select top 1 * from sys_user order by id desc where sex = 1
🌟查前几条——Take(number)
List<sys_user> users = db.Queryable<sys_user>().Take(10)ToList();//查前十条
//select top 10 * from sys_user
🌟是否存在——Any(条件)
bool isExists= db.Queryable<sys_user>().Any(it => it.sex ==1);
🌟排序——OrderBy(排序列,类型)
详见:排序 OrderBy - SqlSugar 5x - .NET果糖网 (donet5.com)
var list =db.Queryable<Student>()
.LeftJoin<School>((st, sc) =>st.SchoolId==sc.Id)//两表关联
.OrderBy((st,sc)=>st.SchoolId)//写Select前面用法,正常都这么用;按照学校id排序
.Select((st,sc)=>new Dto(){ id=it.id ,Name=it.Name})
.ToList();
🌟最大值max;最小值min;求和Sum;平均值Avg
db.Queryable<Order>().Max(it=>it.Id);//四个函数用法一样
🌟分页查询——ToPageList(多参数)---可以用 ToOffsetPage 取代 ToPageList
详见分页查询,同步分页和异步分页 - SqlSugar 5x - .NET果糖网 (donet5.com)
//多表分页var list = db.Queryable<Student>().LeftJoin<School>((st,sc)=>st.SchoolId==sc.Id).Select((st,sc)=>new{Id=st.Id,Name=st.Name,SchoolName=sc.Name}).ToPageList(pageIndex, pageSize, ref totalCount,ref totalPage);
🌟多表联查——左连接.LeftJoin或者new JoinQueryInfos
详见联表查询、关联查询、JoinTable、连表查询、Left Join - SqlSugar 5x - .NET果糖网 (donet5.com)
db.Queryable<Order, OrderItem, Custom>((o, i, c) => new JoinQueryInfos(JoinType.Left, o.Id == i.OrderId, //左连接 左链接 左联 JoinType.Left, o.CustomId == c.Id
))
.Select((o,i,c)=>new ViewModel{ name=o.Name ..})
.ToList()
//那么生成的Sql就是
// FROM [Order] o
// Left JOIN [OrderItem] i ON ( [o].[Id] = [i].[OrderId] )
// Left JOIN [Custom] c ON ( [o].[CustomId] = [c].[Id] )
//联表查询
var query5 = db.Queryable<Order>().LeftJoin<Custom>((o,cus) => o.CustomId == cus.Id)//多个条件用&&.LeftJoin<OrderDetail> ((o,cus,oritem) => o.Id == oritem.OrderId).Where(o => o.Id == 1) .Select((o,cus,oritem) => new ViewOrder {Id=o.Id,CustomName = cus.Name }).ToList(); // SELECT
// [o].[Id] AS [Id],
// [cus].[Name] AS [CustomName]
// FROM
// [Order] o
// Left JOIN [Custom] cus ON ([o].[CustomId] = [cus].[Id])
// Left JOIN [OrderDetail] oritem ON ([o].[Id] = [oritem].[OrderId])
// WHERE
// ([o].[Id] = @Id0)
6、控制台输出SQL语句-Aop.OnLogExecuting🚩
运行过的增删改查对应的SQL语句可打印到控制台
db.Aop.OnLogExecuting = (sql, par) =>{Console.WriteLine($"SQL语句:{sql}");};
// See https://aka.ms/new-console-template for more informationusing Models;
using SqlSugar;Console.WriteLine("Hello, World!");
try
{ConnectionConfig connectionConfig = new ConnectionConfig(){ConnectionString = "Server=localhost;Database=net-vue;User ID=root;Password=root123;",DbType = DbType.MySql,InitKeyType = InitKeyType.Attribute};using (SqlSugarClient db=new SqlSugarClient(connectionConfig)){db.Aop.OnLogExecuting = (sql, par) =>{Console.WriteLine($"SQL语句:{sql}");};List<sys_user> users = db.Queryable<sys_user>().ToList();//查所有int count =db.Queryable<sys_user>().Count();//查总数List<sys_user> user1 = db.Queryable<sys_user>().Where(it => it.sex == 1).ToList();//条件查询List<sys_user> user2 = db.Queryable<sys_user>().Where(it => it.userId == 1&&it.sex==1).ToList();//多条件查询db.Queryable<sys_user>().Where(it => it.avatar.Contains("a")).ToList();//模糊查询bool isExists= db.Queryable<sys_user>().Any(it => it.sex ==1);//是否存在}}
catch (Exception e)
{Console.WriteLine( e.Message);throw;
}
结果: