目录

1.添加包

2.配置连接字符串

 3.配置SqlSugar

        3.1.添加基础类

         3.2.添加方法

        3.2.1.读取配置方法

        3.2.2.枚举扩展方法       

         3.3.添加管理类(重要)

4.配置仓储

        4.1.仓储接口添加

5.注册

6.使用 


        该文档是配置SqlSugar多租户和加仓储教程。使用 SqlSugar 添加仓储层可以带来多方面的优势,尤其在提高代码的可维护性、可测试性和开发效率方面,提升代码的整体质量,促进团队合作,并降低维护成本。这对于长期发展的项目来说尤为重要。

1.添加包

        添加 SqlSugarCore 的NuGet包。

        操作:点击打开到要添加的项目 → 依赖项 → 包 → 右键点击 管理NuGet包

→ 搜索 SqlSugarCore → 安装

2.配置连接字符串

        点击到添加的项目 → 右键添加 → 新建项 → 右上角搜索 json → 修改名字为 dbsettings →添加

        添加自己的数据库连接

{//数据库连接字符串"ConnectionStrings": {"DefaultDbString": "Server=你的数据库地址;Port=数据库端口;Database=数据库名称;User ID=用户;Password=密码;SslMode=Required;","DefaultDbNumber": 0,"DefaultDbType": "MySql","DbConfigs": [{"DbNumber": "1","DbType": "SqlServer","DbString": "Server=你的数据库地址;Initial Catalog=数据库名称;User ID=用户;Password=密码;Encrypt=True;TrustServerCertificate=True;"},{"DbNumber": 2,"DbType": "MySql","DbString": "Server=你的数据库地址;Port=数据库端口;Database=数据库名称;User ID=用户;Password=密码;SslMode=Required;"}]}
}

        案例如下

 3.配置SqlSugar

        3.1.添加基础类

        添加 DbConnEnum 枚举、ConnectionStringsOptions 类、DbConfig 类

 public enum DbConnEnum{/// <summary>/// SqlServer/// </summary>[Description("Mysql")]Default = 0,/// <summary>/// Mysql/// </summary>[Description("Sqlserver")]SystemSqlserver = 1,/// <summary>/// Mysql/// </summary>[Description("Mysql")]SystemMysql = 2,}/// <summary>/// 数据库配置/// </summary>public class ConnectionStringsOptions{/// <summary>/// 默认数据库编号/// </summary>public int DefaultDbNumber { get; set; }/// <summary>/// 默认数据库类型/// </summary>public string DefaultDbType { get; set; }/// <summary>/// 默认数据库连接字符串/// </summary>public string DefaultDbString { get; set; }/// <summary>/// 业务库集合/// </summary>public List<DbConfig> DbConfigs { get; set; }}/// <summary>/// 数据库参数/// </summary>public class DbConfig{/// <summary>/// 数据库编号/// </summary>public string DbNumber { get; set; }/// <summary>/// 数据库类型/// </summary>public string DbType { get; set; }/// <summary>/// 数据库连接字符串/// </summary>public string DbString { get; set; }}

        案例如下

 

         3.2.添加方法

        3.2.1.读取配置方法

        添加获取配置方法

/// <summary>/// 全局配置/// </summary>public static class Config{/// <summary>/// 从指定的 JSON 配置文件中读取配置,并反序列化为指定类型/// </summary>/// <typeparam name="T">目标配置类型(如 RedisSettings、DatabaseSettings 等)</typeparam>/// <param name="fileName">JSON 配置文件名(如 "appsettings.json")</param>/// <param name="sessions">配置节点名称(如 "RedisSettings")</param>/// <returns>返回绑定后的强类型配置对象</returns>public static T GetSetting<T>(string fileName, string sessions){//创建 ConfigurationBuilder 实例,用于构建配置var builder = new ConfigurationBuilder()//设置配置文件的基础路径为当前程序运行目录.SetBasePath(Directory.GetCurrentDirectory())//添加 JSON 文件作为配置源://- fileName: 指定要加载的 JSON 文件//- optional: false 表示文件必须存在,否则抛出异常//- reloadOnChange: true 表示文件修改时自动重新加载.AddJsonFile(fileName, optional: false, reloadOnChange: true);//构建配置对象(IConfigurationRoot)IConfigurationRoot config = builder.Build();//获取指定配置节点(sessions),并将其反序列化为类型 Tvar conn = config.GetSection(sessions).Get<T>();//返回反序列化后的配置对象return conn;}}

        案例如下

        3.2.2.枚举扩展方法       

        添加枚举扩展方法方便扩展枚举

 /// <summary>/// 枚举扩展/// </summary>public static class EnumExtesion{/// <summary>/// 枚举扩展方法 - 获取枚举值的Description特性描述/// </summary>/// <param name="value">枚举值</param>/// <returns>描述内容</returns>public static string Description(this Enum value){// 参数验证if (value == null)throw new ArgumentNullException(nameof(value));// 获取枚举类型的字段信息FieldInfo fi = value.GetType().GetField(value.ToString());// 获取字段上的DescriptionAttribute特性数组DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), // 要查找的特性类型false                        // 不搜索继承链);// 如果有Description特性则返回其描述,否则返回枚举字符串return attributes.Length > 0 ? attributes[0].Description : value.ToString();}}

        案例如下

         3.3.添加管理类(重要)

                SqlSugar数据库上下文管理类,用于管理多数据库连接实例

using Frame4_LibraryCore.BaseConfig;
using Frame6_LibraryUtility.Enum;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using DbType = SqlSugar.DbType;namespace Frame3_DataRepository.SqlSugarRepository
{/// <summary>/// SqlSugar数据库上下文管理类,用于管理多数据库连接实例/// </summary>public class DatabaseSqlSugar{/// <summary>/// 数据库连接字典,按数据库编号存储SqlSugarScope实例/// Key: 数据库编号(int)/// Value: SqlSugarScope实例/// </summary>private readonly Dictionary<int, SqlSugarScope> _dbs = new();/// <summary>/// 主数据库实例(默认操作使用的数据库)/// </summary>public ISqlSugarClient MainDb { get; private set; }/// <summary>/// 构造函数,初始化数据库连接/// </summary>/// <param name="configuration">配置接口,用于获取连接字符串</param>public DatabaseSqlSugar(IConfiguration configuration){// 从配置文件获取数据库连接配置var connectionStringOption = Config.GetSetting<ConnectionStringsOptions>("dbsettings.json", "ConnectionStrings");// 添加默认数据库连接AddDatabase(connectionStringOption.DefaultDbNumber, connectionStringOption.DefaultDbType, connectionStringOption.DefaultDbString);// 添加其他配置的数据库连接if (connectionStringOption.DbConfigs != null){foreach (var config in connectionStringOption.DbConfigs){AddDatabase(int.Parse(config.DbNumber), config.DbType, config.DbString);}}// 设置主数据库实例MainDb = _dbs[connectionStringOption.DefaultDbNumber];}/// <summary>/// 添加数据库连接/// </summary>/// <param name="dbNumber">数据库编号</param>/// <param name="dbType">数据库类型字符串</param>/// <param name="connectionString">连接字符串</param>private void AddDatabase(int dbNumber, string dbType, string connectionString){// 创建SqlSugarScope实例var db = new SqlSugarScope(new ConnectionConfig(){ConnectionString = connectionString,DbType = (DbType)Enum.Parse(typeof(DbType), dbType), // 转换数据库类型枚举IsAutoCloseConnection = true, // 启用自动关闭连接InitKeyType = InitKeyType.Attribute // 使用特性方式初始化主键});// 绑定AOP事件BindAopEvents(db, dbNumber);// 添加到数据库字典_dbs[dbNumber] = db;}/// <summary>/// 根据实体类型获取对应的数据库实例/// </summary>/// <typeparam name="TEntity">实体类型</typeparam>/// <returns>对应的SqlSugarClient实例</returns>/// <exception cref="KeyNotFoundException">当找不到对应的数据库时抛出</exception>public ISqlSugarClient GetDbByEntity<TEntity>(){var type = typeof(TEntity);// 获取实体上的Tenant特性(用于多租户/分库)var tenantAttr = (TenantAttribute)Attribute.GetCustomAttribute(type, typeof(TenantAttribute));// 获取数据库编号,默认为0int dbNumber = (int)tenantAttr.configId != 0 ? (int)tenantAttr.configId : 0;if (_dbs.TryGetValue(dbNumber, out var db)){// 确保AOP事件已绑定BindAopEvents(db, dbNumber);return db;}throw new KeyNotFoundException($"找不到编号为 {dbNumber} 的数据库连接");}/// <summary>/// 绑定AOP事件(主要用于SQL日志记录)/// </summary>/// <param name="db">SqlSugarClient实例</param>/// <param name="dbNumber">数据库编号</param>private void BindAopEvents(ISqlSugarClient db, int dbNumber){// SQL执行完成事件db.Aop.OnLogExecuted = (sql, pars) =>{// 根据SQL类型设置不同颜色if (sql.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase)){Console.ForegroundColor = ConsoleColor.Green; // 查询语句用绿色}else if (sql.TrimStart().StartsWith("DELETE", StringComparison.OrdinalIgnoreCase)){Console.ForegroundColor = ConsoleColor.Red; // 删除语句用红色}else{Console.ForegroundColor = ConsoleColor.Blue; // 其他语句用蓝色}// 构建完整SQL(替换参数)string completeSql = sql;if (pars != null && pars.Length > 0){Dictionary<string, object> parameterValues = new();foreach (var p in pars){parameterValues[p.ParameterName] = p.Value;}foreach (var kvp in parameterValues){completeSql = completeSql.Replace(kvp.Key, FormatParameterValue(kvp.Value));}}// 输出SQL日志Console.WriteLine($"【Sql时间】:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}\r\n" +$"【Sql库号】:{((DbConnEnum)dbNumber).Description()} \r\n" +$"【Sql语句】:{completeSql} \r\n" +$"【Sql耗时】: {db.Ado.SqlExecutionTime.TotalMilliseconds:F2} 毫秒\r\n");};}/// <summary>/// 关闭所有数据库连接/// </summary>public void CloseAllConnections(){foreach (var db in _dbs.Values){db.Dispose(); // 释放数据库连接资源}}/// <summary>/// 格式化参数值,用于SQL日志输出/// </summary>/// <param name="value">参数值</param>/// <returns>格式化后的字符串</returns>private static string FormatParameterValue(object value){if (value is string stringValue){return $"'{stringValue}'"; // 字符串类型加引号}else if (value is DateTime dateTimeValue){return $"'{dateTimeValue.ToString("yyyy-MM-dd HH:mm:ss")}'"; // 日期时间格式化}else if (value is bool boolValue){return boolValue ? "1" : "0"; // 布尔值转数字}else{return value?.ToString() ?? "NULL"; // 其他类型直接转字符串,null值转为NULL}}}
}

         案例如下

4.配置仓储

        基于SqlSugar的通用仓储实现类,提供对实体TEntity的CRUD操作及基础查询功能

using SqlSugar;
using System.Linq.Expressions;namespace Frame3_DataRepository.SqlSugarRepository
{/// <summary>/// 基于SqlSugar的通用仓储实现类/// 提供对实体TEntity的CRUD操作及基础查询功能/// </summary>/// <typeparam name="TEntity">实体类型,必须是引用类型且有公共无参构造函数</typeparam>public class SqlSugarRepository<TEntity> : ISqlSugarRepository<TEntity> where TEntity : class, new(){/// <summary>/// 数据库工厂实例,用于获取数据库连接/// </summary>private readonly DatabaseSqlSugar _dbFactory;/// <summary>/// 构造函数,通过依赖注入初始化数据库工厂/// </summary>/// <param name="dbFactory">数据库工厂实例</param>public SqlSugarRepository(DatabaseSqlSugar dbFactory){_dbFactory = dbFactory;}/// <summary>/// 当前实体对应的数据库客户端/// 根据实体上的TenantAttribute自动选择对应的数据库/// </summary>protected ISqlSugarClient _db => _dbFactory.GetDbByEntity<TEntity>();/// <summary>/// 实体查询集合(延迟加载)/// 可用于构建复杂查询/// </summary>public virtual ISugarQueryable<TEntity> Entities => _db.Queryable<TEntity>();#region 查询方法/// <summary>/// 根据条件表达式获取第一条记录/// </summary>/// <param name="whereExpression">查询条件表达式</param>/// <returns>符合条件的第一条记录,若无则返回null</returns>public TEntity First(Expression<Func<TEntity, bool>> whereExpression){return _db.Queryable<TEntity>().First(whereExpression);}/// <summary>/// 异步获取符合条件的第一条记录/// </summary>/// <param name="whereExpression">查询条件表达式</param>/// <returns>包含查询结果的Task</returns>public async Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> whereExpression){return await _db.Queryable<TEntity>().FirstAsync(whereExpression);}/// <summary>/// 获取所有记录列表/// </summary>/// <returns>实体列表</returns>public List<TEntity> ToList(){return _db.Queryable<TEntity>().ToList();}/// <summary>/// 异步获取所有记录列表/// </summary>/// <returns>包含实体列表的Task</returns>public async Task<List<TEntity>> ToListAsync(){return await _db.Queryable<TEntity>().ToListAsync();}/// <summary>/// 根据主键ID获取实体/// 默认查找名为"Id"的属性作为主键/// </summary>/// <param name="id">主键值</param>/// <returns>对应实体</returns>/// <exception cref="InvalidOperationException">当实体没有Id属性时抛出</exception>public TEntity GetById(object id){var keyProperty = typeof(TEntity).GetProperty("Id");if (keyProperty == null)throw new InvalidOperationException($"实体{typeof(TEntity).Name}不包含Id属性");return _db.Queryable<TEntity>().First(it => keyProperty.GetValue(it).Equals(id));}/// <summary>/// 异步根据主键ID获取实体/// </summary>/// <param name="id">主键值</param>/// <returns>包含查询结果的Task</returns>public async Task<TEntity> GetByIdAsync(object id){var keyProperty = typeof(TEntity).GetProperty("Id");if (keyProperty == null)throw new InvalidOperationException($"实体{typeof(TEntity).Name}不包含Id属性");return await _db.Queryable<TEntity>().FirstAsync(it => keyProperty.GetValue(it).Equals(id));}#endregion#region 新增方法/// <summary>/// 插入单个实体/// </summary>/// <param name="entity">要插入的实体</param>/// <returns>影响的行数</returns>public int Insert(TEntity entity){return _db.Insertable(entity).ExecuteCommand();}/// <summary>/// 批量插入实体集合/// </summary>/// <param name="entity">实体集合</param>/// <returns>影响的行数</returns>public int Insert(List<TEntity> entity){return _db.Insertable(entity).ExecuteCommand();}/// <summary>/// 异步插入单个实体/// </summary>/// <param name="entity">要插入的实体</param>/// <returns>包含影响行数的Task</returns>public async Task<int> InsertAsync(TEntity entity){return await _db.Insertable(entity).ExecuteCommandAsync();}/// <summary>/// 异步批量插入实体集合/// </summary>/// <param name="entity">实体集合</param>/// <returns>包含影响行数的Task</returns>public async Task<int> InsertAsync(List<TEntity> entity){return await _db.Insertable(entity).ExecuteCommandAsync();}#endregion#region 更新方法/// <summary>/// 更新单个实体/// 自动忽略null值和默认值字段/// </summary>/// <param name="entity">要更新的实体</param>/// <returns>影响的行数</returns>public int Update(TEntity entity){return _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue: true).ExecuteCommand();}/// <summary>/// 批量更新实体集合/// </summary>/// <param name="entity">实体集合</param>/// <returns>影响的行数</returns>public int Update(List<TEntity> entity){return _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue: true).ExecuteCommand();}/// <summary>/// 异步更新单个实体/// </summary>/// <param name="entity">要更新的实体</param>/// <returns>包含影响行数的Task</returns>public async Task<int> UpdateAsync(TEntity entity){return await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue: true).ExecuteCommandAsync();}/// <summary>/// 异步批量更新实体集合/// </summary>/// <param name="entity">实体集合</param>/// <returns>包含影响行数的Task</returns>public async Task<int> UpdateAsync(List<TEntity> entity){return await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue: true).ExecuteCommandAsync();}/// <summary>/// 高性能批量更新/// </summary>/// <param name="entity">实体集合</param>/// <returns>影响的行数</returns>/// <exception cref="ArgumentException">当实体集合为空时抛出</exception>public int BulkUpdate(List<TEntity> entity){if (entity == null || !entity.Any())throw new ArgumentException("更新实体集合不能为空");return _db.Fastest<TEntity>().BulkUpdate(entity);}/// <summary>/// 异步高性能批量更新/// </summary>/// <param name="entity">实体集合</param>/// <returns>包含影响行数的Task</returns>public async Task<int> BulkUpdateAsync(List<TEntity> entity){if (entity == null || !entity.Any())throw new ArgumentException("更新实体集合不能为空");return await _db.Fastest<TEntity>().BulkUpdateAsync(entity);}#endregion#region 删除方法/// <summary>/// 根据主键ID删除记录/// </summary>/// <param name="id">主键值</param>/// <returns>影响的行数</returns>/// <exception cref="InvalidOperationException">当实体没有Id属性时抛出</exception>public int DeleteById(object id){var keyProperty = typeof(TEntity).GetProperty("Id");if (keyProperty == null)throw new InvalidOperationException($"实体{typeof(TEntity).Name}不包含Id属性");var expression = Expression.Lambda<Func<TEntity, bool>>(Expression.Equal(Expression.Property(Expression.Parameter(typeof(TEntity), "it"), "Id"),Expression.Constant(id)),new[] { Expression.Parameter(typeof(TEntity), "it") });return _db.Deleteable<TEntity>().Where(expression).ExecuteCommand();}/// <summary>/// 异步根据主键ID删除记录/// </summary>/// <param name="id">主键值</param>/// <returns>包含影响行数的Task</returns>public async Task<int> DeleteByIdAsync(object id){var keyProperty = typeof(TEntity).GetProperty("Id");if (keyProperty == null)throw new InvalidOperationException($"实体{typeof(TEntity).Name}不包含Id属性");var expression = Expression.Lambda<Func<TEntity, bool>>(Expression.Equal(Expression.Property(Expression.Parameter(typeof(TEntity), "it"), "Id"),Expression.Constant(id)),new[] { Expression.Parameter(typeof(TEntity), "it") });return await _db.Deleteable<TEntity>().Where(expression).ExecuteCommandAsync();}#endregion#region 查询构造器/// <summary>/// 根据条件表达式构建查询/// </summary>/// <param name="predicate">查询条件</param>/// <returns>可继续构建的查询对象</returns>public virtual ISugarQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate){return AsQueryable(predicate);}/// <summary>/// 根据条件构建查询/// 当condition为true时应用predicate条件/// </summary>/// <param name="condition">是否应用条件</param>/// <param name="predicate">查询条件</param>/// <returns>可继续构建的查询对象</returns>public virtual ISugarQueryable<TEntity> Where(bool condition, Expression<Func<TEntity, bool>> predicate){return AsQueryable().WhereIF(condition, predicate);}/// <summary>/// 获取基础查询构造器/// </summary>/// <returns>可继续构建的查询对象</returns>public virtual ISugarQueryable<TEntity> AsQueryable(){return Entities;}/// <summary>/// 根据条件获取查询构造器/// </summary>/// <param name="predicate">查询条件</param>/// <returns>可继续构建的查询对象</returns>public virtual ISugarQueryable<TEntity> AsQueryable(Expression<Func<TEntity, bool>> predicate){return Entities.Where(predicate);}#endregion#region 事务管理/// <summary>/// 在当前数据库开启事务/// </summary>public void CurrentBeginTran(){_db.AsTenant().BeginTran();}/// <summary>/// 提交当前数据库事务/// </summary>public void CurrentCommitTran(){_db.AsTenant().CommitTran();}/// <summary>/// 回滚当前数据库事务/// </summary>public void CurrentRollbackTran(){_db.AsTenant().RollbackTran();}#endregion}
}

        案例如下

        4.1.仓储接口添加

        为了更好的使用仓储,把仓储的每个方法添加接口。

using SqlSugar;
using System.Linq.Expressions;namespace Frame3_DataRepository.SqlSugarRepository
{/// <summary>/// 仓储接口/// </summary>/// <typeparam name="TEntity"></typeparam>public interface ISqlSugarRepository<TEntity> where TEntity : class, new(){/// <summary>/// 查询单条数据/// </summary>/// <param name="whereExpression"></param>/// <returns></returns>TEntity First(Expression<Func<TEntity, bool>> whereExpression);/// <summary>/// 查询单条数据 (异步)/// </summary>/// <param name="whereExpression"></param>/// <returns></returns>Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> whereExpression);/// <summary>/// 获取列表/// </summary>/// <returns></returns>List<TEntity> ToList();/// <summary>/// 获取列表 (异步)/// </summary>/// <returns></returns>Task<List<TEntity>> ToListAsync();/// <summary>/// 根据Id获取数据/// </summary>/// <param name="id"></param>/// <returns></returns>/// <exception cref="InvalidOperationException"></exception>TEntity GetById(object id);/// <summary>/// 根据Id获取数据 (异步)/// </summary>/// <param name="id"></param>/// <returns></returns>/// <exception cref="InvalidOperationException"></exception>Task<TEntity> GetByIdAsync(object id);/// <summary>/// 添加数据/// </summary>/// <param name="entity"></param>/// <returns></returns>int Insert(TEntity entity);/// <summary>/// 批量添加新增数据/// </summary>/// <param name="entity"></param>/// <returns></returns>int Insert(List<TEntity> entity);/// <summary>/// 添加数据 (异步)/// </summary>/// <param name="entity"></param>/// <returns></returns>Task<int> InsertAsync(TEntity entity);/// <summary>/// 批量添加数据 (异步)/// </summary>/// <param name="entity"></param>/// <returns></returns>Task<int> InsertAsync(List<TEntity> entity);/// <summary>/// 修改数据/// </summary>/// <param name="entity"></param>/// <returns></returns>int Update(TEntity entity);/// <summary>/// 批量修改数据/// </summary>/// <param name="entity"></param>/// <returns></returns>int Update(List<TEntity> entity);/// <summary>/// 修改数据 (异步)/// </summary>/// <param name="entity"></param>/// <returns></returns>Task<int> UpdateAsync(TEntity entity);/// <summary>/// 批量修改数据 (异步)/// </summary>/// <param name="entity"></param>/// <returns></returns>Task<int> UpdateAsync(List<TEntity> entity);/// <summary>/// 大批量修改/// </summary>/// <param name="entity"></param>/// <returns></returns>/// <exception cref="ArgumentException"></exception>int BulkUpdate(List<TEntity> entity);/// <summary>/// 大批量修改 (异步)/// </summary>/// <param name="entity"></param>/// <returns></returns>/// <exception cref="ArgumentException"></exception>Task<int> BulkUpdateAsync(List<TEntity> entity);/// <summary>/// 根据Id删除数据/// </summary>/// <param name="id"></param>/// <returns></returns>/// <exception cref="InvalidOperationException"></exception>int DeleteById(object id);/// <summary>/// 根据Id删除数据 (异步)/// </summary>/// <param name="id"></param>/// <returns></returns>/// <exception cref="InvalidOperationException"></exception>Task<int> DeleteByIdAsync(object id);/// <summary>/// 根据表达式查询多条记录/// </summary>/// <param name="predicate"></param>/// <returns></returns>ISugarQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate);/// <summary>/// 根据表达式查询多条记录/// </summary>/// <param name="condition"></param>/// <param name="predicate"></param>/// <returns></returns>ISugarQueryable<TEntity> Where(bool condition, Expression<Func<TEntity, bool>> predicate);/// <summary>/// 构建查询分析器/// </summary>/// <returns></returns>ISugarQueryable<TEntity> AsQueryable();/// <summary>/// 构建查询分析器/// </summary>/// <param name="predicate"></param>/// <returns></returns>ISugarQueryable<TEntity> AsQueryable(Expression<Func<TEntity, bool>> predicate);}
}

        案例如下

5.注册

        添加好以上后就可以把SqlSugar和仓储在文件 Program 或 Startup 里注册。

 // 注册 DatabaseSqlSugar(单例或作用域都可以)builder.Services.AddSingleton<DatabaseSqlSugar>(sp =>{// 假设你有 IConfiguration 可用var configuration = sp.GetRequiredService<IConfiguration>();return new DatabaseSqlSugar(configuration);});// 注册Sqlsugar仓储builder.Services.AddScoped(typeof(ISqlSugarRepository<>), typeof(SqlSugarRepository<>));

6.使用 

        添加 entity 数据库实体类

using Frame6_LibraryUtility.Enum;
using SqlSugar;namespace Frame2_DataModel.Entity.User
{/// <summary>/// User实体/// </summary>[SugarTable("User", TableDescription = "用户表"), Tenant((int)DbConnEnum.SystemMysql)]public class UserEntity : BaseEntity{/// <summary>/// 用户Id主键/// </summary>[SugarColumn(IsPrimaryKey = true)]public string Id { get; set; }/// <summary>/// 用户登录名/// </summary>public string UserId { get; set; }/// <summary>/// 用户密码/// </summary>public string pwd { get; set; }/// <summary>/// 用户姓名/// </summary>public string UserName { get; set; }public string Age { get; set; }}
}

        案例如下

        使用仓储

 public class UserService : BaseService, IUserService{private readonly ISqlSugarRepository<UserEntity> _dbUser;/// <summary>/// 依赖注入/// </summary>/// <param name="sqlSugar"></param>/// <param name="tokenService"></param>/// <param name="iCurrentUser"></param>/// <param name="mapper"></param>public UserService(ISqlSugarRepository<UserEntity> dbUser){_dbUser = dbUser;}/// <summary>/// 获取所有test/// </summary>/// <returns></returns>public async Task<ResultModel<List<UserEntity>>> GetUserAsync(){var result = new ResultModel<List<UserEntity>>();var users = await _dbUser.ToListAsync();result.Msg = "获取成功";result.Data = users;return result;}}

         案例如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89654.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89654.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/89654.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全国高等院校计算机基础教育研究会2025学术年会在西宁成功举办 ——高原论道启新程,数智融合育英才

7 月16日至18日&#xff0c;全国高等院校计算机基础教育研究会2025学术年会在青海西宁隆重召开。大会以“数智融合&#xff0c;创新计算机教育”为主题&#xff0c;汇聚人工智能领域顶尖专家学者、高校校长、产业翘楚及一线教师300 多人&#xff0c;共商人工智能时代计算机基础…

AppTrace:重新定义免填邀请码,解锁用户裂变新高度

​​在移动互联网时代&#xff0c;​用户裂变是App增长的核心引擎&#xff0c;而邀请机制则是裂变的关键驱动力。然而&#xff0c;传统的邀请码机制——依赖用户手动输入、记忆复杂字符——已经成为用户体验的绊脚石&#xff0c;导致转化率下降、运营成本上升。​AppTrace​ 作…

神经网络常见激活函数 13-Softplus函数

文章目录Softplus函数导函数函数和导函数图像优缺点PyTorch 中的 Softplus 函数TensorFlow 中的 Softplus 函数Softplus 函数导函数 Softplus函数 Softplus⁡(x)ln⁡(1ex)\begin{aligned} \operatorname{Softplus}(x) & \ln \bigl(1 e^{\,x}\bigr) \end{aligned} Softplu…

深度理解 KVM:Linux 内核系统学习的重要角度

&#x1f4d6; 推荐阅读&#xff1a;《Yocto项目实战教程:高效定制嵌入式Linux系统》 &#x1f3a5; 更多学习视频请关注 B 站&#xff1a;嵌入式Jerry 深度理解 KVM&#xff1a;Linux 内核系统学习的重要角度 作者&#xff1a;嵌入式 Jerry 一、为什么开发者需要学习 KVM&…

闭包的定义和应用场景

一、闭包是什么&#xff1f; 闭包是指函数可以“记住”并访问它定义时的词法作用域&#xff0c;即使这个函数在其作用域链之外执行。 简单说&#xff1a;函数 A 在函数 B 中被定义&#xff0c;并在函数 B 外部被调用&#xff0c;它依然能访问函数 B 中的变量&#xff0c;这就是…

北京-4年功能测试2年空窗-报培训班学测开-第五十四天

今天交付的成果是&#xff0c;初版简历虽然只写了项目部分&#xff0c;但用了一整天&#xff0c;期间联系了前司组长&#xff0c;拿到了性能测试报告。然后再看压测脚本&#xff0c;突然能看懂了&#xff0c;对服务端日志也能看懂些了&#xff0c;还找到了客户端日志怎么说呢&a…

算法训练营day24 回溯算法③ 93.复原IP地址 、78.子集、 90.子集II

今天继续回溯算法的专题&#xff0c;第三篇博客&#xff01; 93.复原IP地址 输入&#xff1a;s "25525511135" 输出&#xff1a;["255.255.11.135","255.255.111.35"] 切割字符串为4段&#xff0c;当进行到第四段的时候对第四段字符串进行判断…

jeccg-boot框架实现xls模板导出功能

文章目录一、后端部分二、前端部分三、模板制作一、后端部分 //1、在application-dev.yml文件增加模板路径path :#模板路径saxls: /data/opt/saxls/ //2、控制层写法 public class sabassalController extends JeecgController<sabassalVo, IsabassalService> {Autowired…

LangChain4j入门:Java开发者的AI应用开发指南

&#x1f680; 在AI浪潮席卷全球的今天&#xff0c;Java开发者如何快速上手大语言模型应用开发&#xff1f;LangChain4j为我们提供了完美的解决方案&#xff01; 前言&#xff1a;为什么Java开发者需要LangChain4j&#xff1f; 想象一下&#xff0c;你正在开发一个企业级应用&…

相机光学(五十)——Depth AF

1.什么是Depth AFDepth AF&#xff08;景深自动对焦&#xff09;&#xff0c;也称为 Depth-of-Field AF&#xff08;景深对焦&#xff09; 或 DEP AF&#xff0c;是一种基于景深范围的自动对焦技术&#xff0c;核心目标是&#xff1a;确保从前景到背景的一整段距离都在清晰景深…

Unity 堆栈分析实战指南 C#

Unity 堆栈分析实战指南 提示&#xff1a;内容纯个人编写&#xff0c;欢迎评论点赞&#xff0c;来指正我。 文章目录Unity 堆栈分析实战指南1. 前言2. 什么是堆栈3. Unity 中的堆栈4. 堆栈分析工具5. 如何进行堆栈分析6. 实战案例分析案例 1: 性能瓶颈分析案例 2: 内存泄漏检测…

AE MDX L6 L12 L18 电源手侧操作使用说明

AE MDX L6 L12 L18 电源手侧操作使用说明

Gemini Function Calling 和 Qwen3 Embedding和ReRanker模型

Gemini API 的函数调用&#xff08;Function Calling&#xff09;功能。它解决了传统大语言模型&#xff08;LLM&#xff09;的一个关键局限&#xff1a;LLM 本身是基于训练数据的“知识库”&#xff0c;擅长生成文本和回答问题&#xff0c;但无法直接执行代码、访问实时数据或…

​​VMware Workstation Pro 17.5.0 安装教程 - 详细步骤图解(附下载+激活)​

VMware Workstation Pro 17.5.0 是一款功能强大的虚拟机软件&#xff0c;允许用户在一台计算机上同时运行多个操作系统&#xff08;如 Windows、Linux、macOS&#xff09;&#xff0c;适用于开发、测试、运维及学习环境搭建。本教程提供 ​​详细安装步骤​​&#xff0c;包括 …

端到端神经网络视频编解码器介绍

一、技术演进&#xff1a;从模块优化到全局智能的范式跃迁 传统编解码器的效率天花板&#xff08;1990-2017&#xff09; 架构局限&#xff1a;H.264/HEVC依赖手工设计的运动估计、DCT变换、熵编码模块&#xff0c;各模块独立优化导致全局效率损失。高分辨率瓶颈&#xff1a;4…

Kubernetes (k8s)环境重启Pod方式总结

前言&#xff1a;在 Kubernetes (k8s) 中&#xff0c;没有直接的命令如 kubectl restart pod 来重启 Pod&#xff0c;因为 Pod 的生命周期由控制器&#xff08;如 Deployments、StatefulSets 或 ReplicaSets&#xff09;管理。重启操作本质上是通过删除并重建 Pod 来实现的&…

OOA、OOD 与 OOP:面向对象范式的核心支柱详解

作为软件系统架构的核心范式&#xff0c;面向对象方法贯穿软件开发生命周期。OOA、OOD 和 OOP 分别代表分析、设计和实现三个关键阶段&#xff0c;共同构成一个连贯的工程体系。一、OOA (Object-Oriented Analysis&#xff0c;面向对象分析) 目标&#xff1a;理解问题域&#x…

GBase 8a 与 Spring Boot + MyBatis 整合实战:从环境搭建到CRUD操作

一、引言 在企业级数据管理场景中&#xff0c;GBase数据库凭借其高性能的数据分析能力和对SQL标准的良好兼容性&#xff0c;成为金融、电信等行业的常用选择。本文将详细演示如何将GBase数据库与Spring Boot、MyBatis框架整合&#xff0c;实现高效的数据持久化操作&#xff0c…

功能安全之BIST的基本原理

BIST&#xff08;Built-In Self-Test&#xff0c;内建自测试&#xff09;是一种将测试功能直接集成到集成电路&#xff08;IC&#xff09;或系统内部的设计方法。其基本原理的核心在于&#xff1a;让被测试电路自身&#xff08;或借助少量专用硬件&#xff09;来生成测试激励、…

Linux 程序地址空间

目录 Ⅰ、什么是程序地址空间&#xff1f; Ⅱ、虚拟地址空间是什么样的&#xff1f; 一、虚拟地址空间和页表 1、什么是页表&#xff1f; 2、什么是虚拟地址空间&#xff1f; 3、什么是vm_area_struct? Ⅲ、为什么要用虚拟地址空间&#xff1f; 一、进程的独立性 二、…