1. 程式人生 > 其它 >SqlSugar_C#版_安裝與使用教程

SqlSugar_C#版_安裝與使用教程

一、安裝:

1、引用NuGet包:

 

2、SqlSugar資料庫連線類-非單例

SqlSugar資料庫連線類-非單例
 /**
*┌──────────────────────────────────────────────────────────────┐
*│ 描    述:SqlSugar資料庫連線類-非單例                                                   
*│ 作    者:執筆小白                                              
*│ 版    本:1.0                                       
*│ 建立時間:2022-12-2 15:40:56                            
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 名稱空間: Repository._Base                               
*│ 類    名:PracticeContext                                     
*└──────────────────────────────────────────────────────────────┘
*/
//using IRepository._Base;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Repository._Base
{
    /// <summary>
    /// 操作SqlSugarClient例項
    /// 這裡用的執行一次建立一個SqlSugarClient,因為有人說SqlSugarClient是非執行緒安全的,所以未做成單例或靜態變數
    /// </summary>
    public class PracticeContext   // : IPracticeContext
    {
        /// <summary>
        /// 資料庫連線字串
        /// ConfigurationManager.AppSettings["DefaultConnection"];
        /// ConfigurationManager.ConnectionStrings["MSSqlConStr"].ConnectionString;
        /// </summary>
        private static readonly string _connectionString = ConfigurationManager.AppSettings["DefaultConnection"];

        /// <summary>
        /// SqlSugarClient物件
        /// </summary>
        public SqlSugarClient Db;

        /// <summary>
        /// 建立一個SqlSugarClient物件
        /// </summary>
        /// <param name="connName">連線字串名稱</param>
        public PracticeContext()
        {
            // 建立SqlSugarClient物件
            Db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = _connectionString,  // 連線字串
                DbType = DbType.MySql,                 // 資料庫型別
                InitKeyType = InitKeyType.Attribute,   // 從特性讀取主鍵和自增列資訊
                IsAutoCloseConnection = true,           // 開啟自動釋放模式,和EF原理一樣

            });
            Db.Ado.CommandTimeOut = 720;  // 12分鐘

            // 每次Sql執行前事件,記錄進行的操作
            Db.Aop.OnLogExecuting = (sql, pars) =>
            {
                StringBuilder sqlStr = new();

                if (sql.StartsWith("UPDATE") || sql.StartsWith("INSERT"))
                {
                    Console.ForegroundColor = ConsoleColor.Blue;
                    sqlStr.AppendLine($"==============將要執行新增/修改操作==============");
                }
                if (sql.StartsWith("DELETE"))
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    sqlStr.AppendLine($"==============將要執行刪除操作==============");
                }
                if (sql.StartsWith("SELECT"))
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    sqlStr.AppendLine($"==============將要執行查詢操作==============");
                }
                sqlStr.AppendLine("預SQL:");
                sqlStr.AppendLine("    " + sql);

                string sqlPars = Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));
                sqlStr.AppendLine("SQL預傳參:");
                sqlStr.AppendLine("    " + sqlPars);
                Console.WriteLine(sqlStr.ToString());  // 列印
                Console.ForegroundColor = ConsoleColor.White;

                // 記錄執行的資訊

            };

            //每次Sql執行後事件,記錄SQL執行完的資訊
            Db.Aop.OnLogExecuted = (sql, pars) =>
            {
                // 執行時間超過1秒
                if (Db.Ado.SqlExecutionTime.TotalSeconds > 1)
                {
                    StringBuilder sqlPStr = new();
                    sqlPStr.AppendLine($"==============執行了下面的操作==============");
                    var fileName = Db.Ado.SqlStackTrace.FirstFileName;           // 程式碼CS檔名
                    sqlPStr.AppendLine("程式碼CS檔名:"+ fileName);
                    var fileLine = Db.Ado.SqlStackTrace.FirstLine;               // 程式碼行數
                    sqlPStr.AppendLine("程式碼行數:"+ fileLine);
                    var FirstMethodName = Db.Ado.SqlStackTrace.FirstMethodName;  // 方法名
                    sqlPStr.AppendLine("方法名:" + FirstMethodName);
                    sqlPStr.AppendLine("SQL:");
                    sqlPStr.AppendLine("    "+ sql);
                    var sqlPars = Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value));  // 引數
                    sqlPStr.AppendLine("SQL傳參:");
                    sqlPStr.AppendLine("    " + sqlPars);
                    // 列印
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine(sqlPStr); 
                    Console.ForegroundColor = ConsoleColor.White;

                    // 記錄執行的資訊
                    
                }
            };

            // 記錄SQL報錯
            Db.Aop.OnError = (exp) =>
            {
                StringBuilder sqlStr = new();
                sqlStr.AppendLine($"==============資料庫執行報錯==============");
                sqlStr.AppendLine("SQL: ");
                sqlStr.AppendLine("    " + exp.Sql);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(sqlStr);   // 列印
                Console.ForegroundColor = ConsoleColor.White;
                // 記錄執行的資訊
            };
        }

        /// <summary>
        /// 驗證是否連線成功
        /// 注:一般長連線使用,即IsAutoCloseConnection=true時;=false時使用較少
        /// </summary>
        /// <returns></returns>
        public bool IsValidConnection()
        {
            return Db.Ado.IsValidConnection();
        }

        /// <summary>
        /// 根據資料表生成Entity(實體),
        /// 帶有特徵
        /// 帶有預設值
        /// </summary>
        /// <param name="classNameSpace">指定類的包名</param>
        /// <param name="tableName">指定表名;不指定時生成資料庫中所有表的實體</param>
        /// <param name="isStartsWith_TableName">生成表名以指定關鍵字為開頭的表</param>
        public void DBFirst(string classNameSpace, string tableName = null,bool isStartsWith_TableName = false)
        {
            // 生成的目錄
            string filePath = System.Environment.CurrentDirectory.ToString() + "/EntityFile";
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }

            if (string.IsNullOrEmpty(tableName))  // 生成資料庫中所有表的實體
            {
                Db.DbFirst.IsCreateAttribute().IsCreateDefaultValue().CreateClassFile(filePath, classNameSpace);
            }
            else if(isStartsWith_TableName)  // 生成資料庫中生成表名以指定關鍵字為開頭的表
            {
                Db.DbFirst.Where(it => it.StartsWith(tableName)).IsCreateAttribute().IsCreateDefaultValue().CreateClassFile(filePath, classNameSpace);
            }
            else  // 生成資料庫中指定表名的實體
            {
                Db.DbFirst.Where("tableName").IsCreateAttribute().IsCreateDefaultValue().CreateClassFile(filePath, classNameSpace);
            }
            Console.WriteLine("輸出目錄:"+ filePath);
        }

        /// <summary>
        /// 根據Entity(實體)生成資料庫中的表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity">指定Entity名;不指定時生成指定作用域中/預設作用域(一般指資料夾名)下所有Entity的表結構</param>
        /// <param name="dllName">指定類的包名</param>
        /// <param name="classNameSpaces">指定類的包名</param>
        public void CodeFirst<T>(T entity = null, string dllName= "BOZHON.Repository.dll", string[] classNameSpaces =null) where T : class, new()
        {
            classNameSpaces ??= new string[] { "Entity" };

            if (entity is null)
            {
                var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"/";
                List<Type> entitylist = new();
                if (!string.IsNullOrWhiteSpace(dllName))
                {
                    dllName = path + dllName;
                    Assembly assembly = Assembly.LoadFrom(dllName);
                    Type[] ts = assembly.GetTypes();
                    foreach (string classNameSpace in classNameSpaces)
                    {
                        foreach (Type t in ts)
                        {
                            if (t.FullName.Contains(classNameSpace))
                            {
                                entitylist.Add(t);
                            }
                        }
                    }
                }
                Db.CodeFirst.SetStringDefaultLength(255).InitTables(entitylist.ToArray());
            }
            else
            {
                Db.CodeFirst.SetStringDefaultLength(255).InitTables(typeof(T));
            }
        }
    }
}

二、SqlSugar使用教程:

1、SqlSugar特徵講解

實體示例-SqlSugar特徵講解
/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描    述:示例表                                                  
*│ 作    者:執筆小白                                              
*│ 版    本:1.0                                       
*│ 建立時間:2022-12-2 15:40:56                            
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 名稱空間: Repository._Base                               
*│ 類    名:TestTable                                     
*└──────────────────────────────────────────────────────────────┘
*/
    /// <summary>
    /// 示例表
    /// SugarTable(表名,表描述,isDisabledDelete:禁止刪除列,isCreateTableFieldSort:建立表時對欄位進行排序)
    /// </summary>
    [SugarTable("testtable", "示例表", false, false)]
    public class TestTable
    {
        /// <summary>
        /// 主鍵ID
        /// 不空、主鍵、自增、列名、說明
        /// </summary>
        [SugarColumn(IsNullable = false, IsPrimaryKey = true,IsIdentity=true,ColumnName = "Id",ColumnDescription = "主鍵ID")]
        public int Id { get; set; }

        /// <summary>
        /// 
        /// OldColumnName:將Uname列名改為Name
        /// IndexGroupNameList:索引
        /// </summary>
        [SugarColumn(OldColumnName = "UName", ColumnDataType = "nvarchar", Length = 32, IsNullable = false, IndexGroupNameList = new string[] { "index_UName" })]
        public string Name { get; set; } = string.Empty;

        /// <summary>
        /// 
        /// </summary>
        [SugarColumn(ColumnDataType = "varchar", Length = 32, IsNullable = false)]
        public string Pwd { get; set; } = string.Empty;

        /// <summary>
        /// 
        /// UniqueGroupNameList:唯一索引
        /// </summary>
        [SugarColumn(IsNullable = false,UniqueGroupNameList =new string[] { "index_FId" })]
        public int FId { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public bool IsDelete { get; set; }

        /// <summary>
        /// IsIgnore :ORM不處理該列
        /// IsOnlyIgnoreInsert :插入操作時不處理該列
        /// length=5 長度5 decimal(5,2) 
        /// DecimalDigits=2 :精度2 decimal(5,2) 
        /// </summary>ColumnDescription 備註
        [SugarColumn(IsIgnore = true, IsOnlyIgnoreInsert=true, Length = 5, DecimalDigits = 2)]
        public float dd { get; set; }
    }

2、增刪改查等常見示例

常用示例-簡寫
/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描    述:SqlSugar使用示例                                                  
*│ 作    者:執筆小白                                              
*│ 版    本:1.0                                       
*│ 建立時間:2022-12-2 15:40:56                            
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 名稱空間: Repository._Base                               
*│ 類    名:UseSqlSugarDemo                                     
*└──────────────────────────────────────────────────────────────┘
*/
using Repository._Base;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;

namespace Repository
{
    /// <summary>
    /// SqlSugar使用Demo
    /// </summary>
    public class UseSqlSugarDemo : PracticeContext
    {
        #region sql
        /// <summary>
        /// 執行sql(增刪改)
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public bool SqlExecuteCommand(string sql)
        {
            if (string.IsNullOrEmpty(sql)) return true;

            int count = Db.Ado.ExecuteCommand(sql);
            return count > 0;
        }
        #endregion sql

        #region 查詢
        /// <summary>
        /// 查詢所有實體-返回List示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <returns></returns>
        public List<T> Queryable<T>(string tableName = "") where T : class, new()
        {
            var sugar = Db.Queryable<T>();
            return string.IsNullOrEmpty(tableName) ? sugar.ToList() : sugar.AS(tableName).ToList();
        }

        /// <summary>
        /// 查詢所有實體-返回DataTable示例
        /// 有報錯 DataTable already belongs to another DataSet,已重新宣告
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <returns></returns>
        public DataTable QueryableToDataTable<T>(string tableName = "")
        {
            var sugar = Db.Queryable<T>();
            return string.IsNullOrEmpty(tableName) ? sugar.ToDataTable().Copy() : sugar.AS(tableName).ToDataTable().Copy();  // 原datatable有自己的資料集,需要重新宣告一個
        }

        /// <summary>
        /// 根據表示式查詢-List
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="expression">Where條件</param>
        /// <param name="tableName">別名表</param>
        /// <returns></returns>
        public List<T> Queryable<T>(Expression<Func<T, bool>> expression, string tableName = "") where T : class, new()
        {
            var sugar = Db.Queryable<T>().Where(expression);
            return string.IsNullOrEmpty(tableName) ? sugar.ToList() : sugar.AS(tableName).ToList();
        }

        /// <summary>
        /// 根據表示式查詢-DataTable
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="expression">Where條件</param>
        /// <param name="tableName">別名表</param>
        /// <returns></returns>
        public DataTable Queryable1<T>(Expression<Func<T, bool>> expression, string tableName = "")
        {
            var sugar = Db.Queryable<T>().Where(expression);
            return string.IsNullOrEmpty(tableName) ? sugar.ToDataTable().Copy() : sugar.AS(tableName).ToDataTable().Copy();  // 原datatable有自己的資料集,需要重新宣告一個
        }

        /// <summary>
        /// SQL語句查詢-List示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="sql">SQL執行語句</param>
        /// <returns></returns>
        public List<T> SqlQueryable<T>(string sql) where T : class, new()
        {
            return Db.SqlQueryable<T>(sql).ToList();
        }

        /// <summary>
        /// SQL語句查詢-DataTable示例
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public DataTable SqlQueryable(string sql)
        {
            return Db.SqlQueryable<DataTable>(sql).ToDataTable().Copy();
        }
        #endregion

        #region 新增
        /// <summary>
        /// 新增示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="insertObj">資料</param>
        /// <param name="tableName">別名表</param>
        /// <returns>狀態</returns>
        public bool Insert<T>(T insertObj, string tableName = "") where T : class, new()
        {
            if (insertObj == null) return true;

            IInsertable<T> sugar = Db.Insertable(insertObj);
            return string.IsNullOrEmpty(tableName) ? sugar.ExecuteCommandIdentityIntoEntity() : sugar.AS(tableName).ExecuteCommandIdentityIntoEntity();
        }

        /// <summary>
        /// 批量新增示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="insertObjs">資料</param>
        /// <param name="tableName">別名表</param>
        /// <returns>狀態</returns>
        public bool Insert<T>(List<T> insertObjs, string tableName = "") where T : class, new()
        {
            if (!insertObjs.Any()) return true;

            do
            {
                List<T> tempParam = insertObjs.Take(500).ToList();  // 限制最多500條執行
                IInsertable<T> sugar = Db.Insertable(tempParam);
                bool isSuc = string.IsNullOrEmpty(tableName) ? sugar.ExecuteCommandIdentityIntoEntity() : sugar.AS(tableName).ExecuteCommandIdentityIntoEntity();
                insertObjs.RemoveRange(0, tempParam.Count);
            }
            while (insertObjs.Count > 0);
            return true;
        }
        #endregion 新增

        #region 修改
        /// <summary>
        /// 根據主鍵修改示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="UpdateObj">資料</param>
        /// <param name="tableName">別名表</param>
        /// <returns>狀態</returns>
        public bool Update<T>(T UpdateObj, string tableName = "") where T : class, new()
        {
            if (UpdateObj == null) return true;

            IUpdateable<T> sugar = Db.Updateable(UpdateObj);
            return string.IsNullOrEmpty(tableName) ? sugar.ExecuteCommandHasChange() : sugar.AS(tableName).ExecuteCommandHasChange();
        }

        /// <summary>
        /// 根據主鍵修改_實體指定列示例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="UpdateObj">資料</param>
        /// <param name="columns">需要更新的實體列</param>
        /// <param name="tableName">別名表</param>
        /// <returns></returns>
        public bool Update<T>(T UpdateObj, Expression<Func<T, object>> columns, string tableName = "") where T : class, new()
        {
            if (UpdateObj == null) return true;

            IUpdateable<T> sugar = Db.Updateable(UpdateObj).UpdateColumns(columns);
            return string.IsNullOrEmpty(tableName) ? sugar.ExecuteCommandHasChange() : sugar.AS(tableName).ExecuteCommandHasChange();
        }

        /// <summary>
        /// 根據主鍵批量修改示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="UpdateObjs">資料</param>
        /// <param name="tableName">別名表</param>
        /// <returns>狀態</returns>
        public bool Update<T>(List<T> UpdateObjs, string tableName = "") where T : class, new()
        {
            if (!UpdateObjs.Any()) return true;

            do
            {
                List<T> tempParam = UpdateObjs.Take(500).ToList();  // 限制每次最多修改500條
                IUpdateable<T> sugar = Db.Updateable(tempParam);
                bool isSuc = string.IsNullOrEmpty(tableName) ? sugar.ExecuteCommandHasChange() : sugar.AS(tableName).ExecuteCommandHasChange();
                UpdateObjs.RemoveRange(0, tempParam.Count);
            }
            while (UpdateObjs.Count > 0);
            return true;
        }
        #endregion

        #region 刪除
        /// <summary>
        /// 根據主鍵刪除示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <typeparam name="PkType">主鍵型別</typeparam>
        /// <param name="primaryKeyValue">主鍵</param>
        /// <param name="tableName">別名表</param>
        /// <returns>狀態</returns>
        public bool Deleteable<T, PkType>(PkType primaryKeyValue, string tableName = "") where T : class, new()
        {
            IDeleteable<T> sugar = Db.Deleteable<T>().In(primaryKeyValue);
            return string.IsNullOrEmpty(tableName) ? sugar.ExecuteCommandHasChange() : sugar.AS(tableName).ExecuteCommandHasChange();
        }

        /// <summary>
        /// 根據表示式刪除示例
        /// </summary>
        /// <typeparam name="T">實體</typeparam>
        /// <param name="expression">Where條件</param>
        /// <param name="tableName">別名表</param>
        /// <returns>狀態</returns>
        public bool Deleteable<T>(Expression<Func<T, bool>> expression, string tableName = "") where T : class, new()
        {
            IDeleteable<T> sugar = Db.Deleteable<T>().Where(expression);
            return string.IsNullOrEmpty(tableName) ? sugar.ExecuteCommandHasChange() : sugar.AS(tableName).ExecuteCommandHasChange();
        }
        #endregion

        #region 事務
        /// <summary>
        /// 執行事務示例
        /// </summary>
        /// <returns></returns>
        public bool RunTransactionDemo(string sql)
        {
            try
            {
                TestTable testTable = new TestTable();

                Db.Ado.BeginTran();   // 事務開始
                if (!string.IsNullOrEmpty(sql))
                {
                    Db.Ado.ExecuteCommand(sql);  // 執行sql
                }
                Db.Insertable<TestTable>(testTable).ExecuteCommand();  // 增
                Db.Deleteable<TestTable>(testTable).ExecuteCommand();  // 刪
                Db.Updateable<TestTable>(testTable).ExecuteCommand();  // 改
                Db.Ado.CommitTran();  // 事務提交

                return true;
            }
            catch (Exception ex)
            {
                Db.Ado.RollbackTran();  // 事務回滾

                // 記錄日誌
                string str = ex.StackTrace ?? string.Empty;
                Debug.WriteLine(string.Concat("UI執行緒異常;異常位置:", str.AsSpan(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1), ";異常資訊:", ex.Message));
                return false;
            }
        }
        #endregion 事務
    }

    /// <summary>
    /// 示例表
    /// SugarTable(表名,表描述,isDisabledDelete:禁止刪除列,isCreateTableFieldSort:建立表時對欄位進行排序)
    /// </summary>
    [SugarTable("testtable", "示例表", false, false)]
    public class TestTable
    {
        /// <summary>
        /// 主鍵ID
        /// 不空、主鍵、自增、列名、說明
        /// </summary>
        [SugarColumn(IsNullable = false, IsPrimaryKey = true,IsIdentity=true,ColumnName = "Id",ColumnDescription = "主鍵ID")]
        public int Id { get; set; }

        /// <summary>
        /// 
        /// OldColumnName:將Uname列名改為Name
        /// IndexGroupNameList:索引
        /// </summary>
        [SugarColumn(OldColumnName = "UName", ColumnDataType = "nvarchar", Length = 32, IsNullable = false, IndexGroupNameList = new string[] { "index_UName" })]
        public string Name { get; set; } = string.Empty;

        /// <summary>
        /// 
        /// </summary>
        [SugarColumn(ColumnDataType = "varchar", Length = 32, IsNullable = false)]
        public string Pwd { get; set; } = string.Empty;

        /// <summary>
        /// 
        /// UniqueGroupNameList:唯一索引
        /// </summary>
        [SugarColumn(IsNullable = false,UniqueGroupNameList =new string[] { "index_FId" })]
        public int FId { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public bool IsDelete { get; set; }

        /// <summary>
        /// IsIgnore :ORM不處理該列
        /// IsOnlyIgnoreInsert :插入操作時不處理該列
        /// length=5 長度5 decimal(5,2) 
        /// DecimalDigits=2 :精度2 decimal(5,2) 
        /// </summary>ColumnDescription 備註
        [SugarColumn(IsIgnore = true, IsOnlyIgnoreInsert=true, Length = 5, DecimalDigits = 2)]
        public float dd { get; set; }
    }
}