十年河东,十年河西,莫欺少年穷
学无止境,精益求精
开发过.NetCore 的都知道,微软的EF框架EFCore对DataTable并不是特别友好,在整个EFCore框架中,直接写SQL语句似乎不太行,因此,在我们的项目中就有必要对数据库操作进行扩展。
自上篇博客 netCore 引用第三方ORM中间件-Dapper 后,我在项目架构时将Dapper引入到数据库操作层,使用后,我发现Dapper对 IQueryable 的支持几乎没有,【也可能有,但是我没发现】,这对于追求性能的开发人员来说难以接受,因此,今天引入sqlSugar。
Dapper的查询方法:
由上图可知,Dapper 支持IEnumerable ,IEnumerable 和 IQueryable 的区别是前者将数据全部加载到内存,后者是将需要的数据加载到内存。因此,IE比较浪费内存,IQ相对而言是按需开辟内存,因此,我选择IQ,虽说IQ在某些性能方面比不上IE,但现在的系统,大多都是数据量庞大的。
现在进入正题,sqlSugar的搭建。
俗话说:工欲善其事必先利其器,因此,在项目搭建之前,我们需要准备一个小的数据库。
简单的数据库,只有两张表,
1、打开VS,新建一个netCore3.1的控制台程序,并新增两个类库,如下:
2、SugarEntity为实体层,实体层代码有项目或工具生成,当然,也可以手写。注:需要引入:SqlASugar V 5.0.0.19 版本。
SugarContext为数据上下文层,用于操作数据库,代码也可以通过项目或工具生成,当然,也可以手写。注:需要引入:SqlASugar V 5.0.0.19 版本 和 Newtonsoft.Json V 12.0.3 及 System.Data.SqlClient V 4.8.2 版本
SugarCore为控制台输出层,需要引入SqlASugar V 5.0.0.19 版本
关于上述的【可通过项目/工具生成】大家可参考:http://www.codeisbug.com/Doc/8/1123 或者 直接去CSDN 上下载相关工具/项目:https://download.csdn.net/download/wolongbb/12997789
这里,将代码生成工具截图如下:
工具仅能生成实体类,并不能生成上下文层
重要的话,再说一遍,不管是那一层,我们都可以通过手动写代码的形式实现
3、更层次代码:
3.1、实体层Entity代码如下
Student 实体层
using System;
using System.Linq;
using System.Text;
using SqlSugar;
namespace Sugar.Enties
{
///<summary>
///
///</summary>
[SugarTable("Student")]
public partial class Student
{
public Student(){
}
/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey=true)]
public string StudentID {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string GradID {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string StudentName {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string StudentSex {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public DateTime? CreateTime {get;set;}
}
}
StudentGrad 实体层
using System;
using System.Linq;
using System.Text;
using SqlSugar;
namespace Sugar.Enties
{
///<summary>
///
///</summary>
[SugarTable("StudentGrad")]
public partial class StudentGrad
{
public StudentGrad(){
}
/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey=true)]
public string GradID {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string GradName {get;set;}
/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public DateTime? CreateTime {get;set;}
}
}
3.2、上下文层代码如下:
using SqlSugar;
using Sugar.Enties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace SugarContext
{
public class SugarDbContext<T> where T : class, new()
{
public SugarDbContext()
{
Db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "Data Source=LAPTOP-P5GVS4UM;Initial Catalog=StudentDB;Integrated Security=True",
DbType = DbType.SqlServer,
InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
});
//调式代码 用来打印SQL
Db.Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine(sql + "\r\n" +
Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
Console.WriteLine();
};
}
//注意:不能写成静态的
public SqlSugarClient Db;//用来处理事务多表查询和复杂的操作
public SimpleClient<T> CurrentDb { get { return new SimpleClient<T>(Db); } }//用来操作当前表的数据
public SimpleClient<StudentGrad> StudentGradDb { get { return new SimpleClient<StudentGrad>(Db); } }//用来处理StudentGrad表的常用操作
public SimpleClient<Student> StudentDb { get { return new SimpleClient<Student>(Db); } }//用来处理Student表的常用操作
/// <summary>
/// 获取所有
/// </summary>
/// <returns></returns>
public virtual List<T> GetList()
{
return CurrentDb.GetList();
}
/// <summary>
/// 根据表达式查询
/// </summary>
/// <returns></returns>
public virtual List<T> GetList(Expression<Func<T, bool>> whereExpression)
{
return CurrentDb.GetList(whereExpression);
}
/// <summary>
/// 根据表达式查询分页
/// </summary>
/// <returns></returns>
public virtual List<T> GetPageList(Expression<Func<T, bool>> whereExpression, PageModel pageModel)
{
return CurrentDb.GetPageList(whereExpression, pageModel);
}
/// <summary>
/// 根据表达式查询分页并排序
/// </summary>
/// <param name="whereExpression">it</param>
/// <param name="pageModel"></param>
/// <param name="orderByExpression">it=>it.id或者it=>new{it.id,it.name}</param>
/// <param name="orderByType">OrderByType.Desc</param>
/// <returns></returns>
public virtual List<T> GetPageList(Expression<Func<T, bool>> whereExpression, PageModel pageModel, Expression<Func<T, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
{
return CurrentDb.GetPageList(whereExpression, pageModel, orderByExpression, orderByType);
}
/// <summary>
/// 根据主键查询
/// </summary>
/// <returns></returns>
public virtual T GetById(dynamic id)
{
return CurrentDb.GetById(id);
}
/// <summary>
/// 根据主键删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Delete(dynamic id)
{
return CurrentDb.Delete(id);
}
/// <summary>
/// 根据实体删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Delete(T data)
{
return CurrentDb.Delete(data);
}
/// <summary>
/// 根据主键删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Delete(dynamic[] ids)
{
return CurrentDb.AsDeleteable().In(ids).ExecuteCommand() > 0;
}
/// <summary>
/// 根据表达式删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Delete(Expression<Func<T, bool>> whereExpression)
{
return CurrentDb.Delete(whereExpression);
}
/// <summary>
/// 根据实体更新,实体需要有主键
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Update(T obj)
{
return CurrentDb.Update(obj);
}
/// <summary>
///批量更新
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Update(List<T> objs)
{
return CurrentDb.UpdateRange(objs);
}
/// <summary>
/// 插入
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Insert(T obj)
{
return CurrentDb.Insert(obj);
}
/// <summary>
/// 批量
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual bool Insert(List<T> objs)
{
return CurrentDb.InsertRange(objs);
}
//自已扩展更多方法
}
}
3.3、控制台输出层代码如下:
using SqlSugar;
using Sugar.Enties;
using SugarContext;
using System;
namespace SugarCore
{
class Program
{
static void Main(string[] args)
{
SugarDbContext<Student> db = new SugarDbContext<Student>();
var Lst_Qb = db.Db.Queryable<Student>().ToList();
var lst = db.GetList();
var list = db.Db.Queryable<Student, StudentGrad>((st, sc) => new object[] {
JoinType.Inner,st.GradID==sc.GradID})
.Select<ViewModel>().ToList();
foreach (var item in list)
{
Console.WriteLine(item.GradName + item.StudentName);
}
Console.ReadLine();
}
}
class ViewModel
{
public string StudentID { get; set; }
public string GradID { get; set; }
public string StudentName { get; set; }
public string StudentSex { get; set; }
public DateTime? CreateTime { get; set; }
public string GradName { get; set; }
}
}
输出结果为:
由上图可知,使用SqlSugar 框架时,Context层可以直接记录执行的SQL语句。
以上便是整个Sugar项目的搭建,当然,这都是基础demo,现在说说通过项目来生成数据库上下文层及实体层。
通过上述CSDN 可以下载到该项目
:
项目中有生成步骤的详细说明,摘抄如下:
### SoEasyPlatform 代码生成器
## 介绍
一款轻量级开源的代码生成器,相对较动软代码生成器而言要轻量的多,支持多种数据库,所用到dll组件也都在github有源码,代码非常的简单有点基础的看源码可以把生成的项目改成自已的风格。
## 特色
该代码生成器最大的特点就三个简单 ,无需安装,生成的代码 简单并且有教学用例,还有就是调试和修改模版简单。
## 使用步骤
1.从上面的地址下载 SoEasyPlatform到本地
2.解压项目
点击SoEasyPlatform.sln打开项目,重新生成项目会自动下载NUGET 文件
3.配置三个参数
const SqlSugar.DbType dbType = DbType.SqlServer;//数据库类型
const string connectionString = "server=.;uid=sa;pwd=@jhl85661501;database=SqlSugar4XTest";//连接字符串
const string SolutionName = "SoEasyPlatform";//解决方案名称
4.F5运行
5.完成
我们发现两个类库已经添加到解决方案下面了,并且相关的dll的类库引用也帮我们做好了,非常方便,数据库有改动后F5刷新就好了。
执行完成没发现有类库加进来,关掉解决方案重新打开便可以了
## 如何使用生成的代码开发项目
1.新建一个项目
Web项目或者控制台都可以
2.引用生成的类库
3.代码如下
StudentManager m = new StudentManager();
关于Sugar的性能,直接看官方文档即可,据说比EF好的多,比Dapper也要好的多。
插入比赛:
更新比赛:
查询比赛:
等等吧,总之SqlSugar人性化的设计 加 优良的性能赢得了我的心。
爱你, SqlSugar
@天才卧龙的博客
来源:oschina
链接:https://my.oschina.net/u/4261790/blog/4683700