C# SqlSugar:依赖注入与仓储模式实践

news2025/6/12 20:30:42

C# SqlSugar:依赖注入与仓储模式实践

在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受欢迎的一款。它不仅功能强大,还能结合依赖注入和仓储模式,让代码结构更加清晰。接下来,我们就深入剖析一段利用 SqlSugar 实现依赖注入与仓储模式的代码,了解其原理与使用方式。

一、核心代码解析

1. 基础实体类定义

public abstract class BaseEntity
{
   [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
   public virtual int Id { get; set; }
}

BaseEntity作为基础实体类,定义了一个自增长的主键Id,通过SugarColumn特性设置Id为自增主键,后续的实体类都可以继承该类,统一规范实体的基本属性,为数据库表的主键设置提供便利。

2. 仓储类实现

public class Repository<T> : SimpleClient<T> where T : BaseEntity, new()
{
   public Repository(ISqlSugarClient db)
   {
       base.Context = db;
   }
}

Repository<T>类继承自SimpleClient<T>,它是基于 SqlSugar 实现的泛型仓储类。通过构造函数接收ISqlSugarClient类型的数据库客户端实例db,并将其赋值给基类的Context属性,这样在该仓储类中就可以使用SqlSugar提供的各种数据库操作方法,对继承自BaseEntity的实体类T进行数据访问和操作,实现了对数据库操作的封装,符合仓储模式的理念。

3. SqlSugar 初始化配置

public static class SqlSugarInit
{
   private static readonly string connectionKey = "database_connection_key";
   public static void AddSqlSugarSetup(this IServiceCollection services)
   {
       if (services is null)
       {
           throw new ArgumentNullException(nameof(services));
       }


       var config = GetConfig(connectionKey);
       var client = new SqlSugarScope(config);
       services.AddSingleton<ISqlSugarClient>(o => client);

       var models = GetEntities();
       client.DbMaintenance.CreateDatabase();
       client.CodeFirst.SetStringDefaultLength(200).InitTables(models);
   }


   private static ConnectionConfig GetConfig(string connectionKey)
   {
       var connectionString = ConfigurationManager.ConnectionStrings\[connectionKey].ConnectionString;
       var moreSettings = new ConnMoreSettings
       {
           IsAutoRemoveDataCache = true,
           DisableMillisecond = true,
           IsWithNoLockQuery = true,
           SqliteCodeFirstEnableDefaultValue = true,
       };


       var aopEvents = new AopEvents
       {
           OnLogExecuting = (sql, parameters) =>
           {
               parameters.ToList().ForEach(p => sql.Replace(p.ParameterName, p.Value.ToString()));
               var log = string.Join("\r\n", new string[] { "--------", "【SQL语句】:", sql });
               Console.WriteLine(log);
           },
       };


       return new ConnectionConfig
       {
           ConfigId = 1,
           ConnectionString = connectionString,
           DbType = DbType.SqlServer,
           IsAutoCloseConnection = true,
           InitKeyType = InitKeyType.Attribute,
           MoreSettings = moreSettings,
           AopEvents = aopEvents,
           LanguageType = LanguageType.Chinese
       };
   }


   private static Type[] GetEntities()
   {
       return Assembly.GetExecutingAssembly()
          .GetReferencedAssemblies()
          .Select(a => Assembly.Load(a))
          .SelectMany(a => a.GetTypes())
          .Where(t => t.IsSubclassOf(typeof(BaseEntity)))
          .Where(t => t.GetCustomAttributes().Any(a => a is SugarTable))
          .ToArray();
   }
}

SqlSugarInit类负责 SqlSugar 的初始化配置和依赖注入相关操作:

  • AddSqlSugarSetup方法通过扩展IServiceCollection,将 SqlSugar 配置添加到服务集合中。它先获取数据库连接配置config,创建SqlSugarScope实例client,并将ISqlSugarClient以单例模式注册到服务集合,保证整个应用中只有一个SqlSugarClient实例。接着获取所有符合条件的实体类models,使用DbMaintenance.CreateDatabase创建数据库(如果不存在),并通过CodeFirst初始化数据库表结构。
  • GetConfig方法用于获取数据库连接配置信息,从配置文件中读取连接字符串,设置连接的额外参数moreSettings和 AOP 事件aopEvents(这里实现了 SQL 语句执行日志输出功能),最终返回完整的ConnectionConfig对象。
  • GetEntities方法通过反射,从当前程序集及其引用的程序集中,筛选出继承自BaseEntity且带有SugarTable特性的实体类类型数组,以便后续进行数据库表的初始化操作。

二、使用示例

1. 假设我们有一个User实体类:

using SqlSugar;

[SugarTable("Users")]

public class User : BaseEntity
{
   public string Name { get; set; }
   public int Age { get; set; }
}

2. 在应用的启动配置中,注册 SqlSugar 服务:

using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddSqlSugarSetup();
services.AddScoped(typeof(Repository<>));

var serviceProvider = services.BuildServiceProvider();

3. 在业务逻辑中使用仓储类进行数据操作:

class UserService
{
    private readonly Repository<User> userRepository;
    public UserService(Repository<User> userRepository)
    {
        this.userRepository = userRepository;
    }

    public User FindOne(int id)
    {
        return this.userRepository.GetById(id);
    }
}

上述代码中,先创建User实体类并继承BaseEntity,使用SugarTable特性指定数据库表名。在启动配置时,注册 SqlSugar 服务和User实体类对应的仓储服务。在业务逻辑中获取User仓储实例,进行数据插入和查询操作,简洁地实现了数据库交互。

三、优势与注意事项

1. 优势

  • 代码结构清晰:依赖注入和仓储模式的结合,将数据库操作与业务逻辑分离,降低了代码的耦合度,使代码结构更加清晰,便于维护和扩展。
  • 提高开发效率:SqlSugar 提供了丰富的数据库操作方法,通过仓储类的封装,开发者无需重复编写基础的数据访问代码,提高了开发效率。
  • 统一规范BaseEntity类和统一的配置方式,为实体类和数据库操作建立了统一的规范,保证了代码的一致性和规范性。

2. 注意事项

  • 数据库连接字符串配置:确保ConfigurationManager.ConnectionStrings中配置的连接字符串正确,否则无法建立数据库连接。在不同的环境(开发、测试、生产)中,要注意切换相应的配置。
  • 实体类特性使用:使用SugarTableSugarColumn等特性时,要准确设置属性,避免因特性设置错误导致数据库表结构创建或数据映射出现问题。
  • 单例模式的影响ISqlSugarClient以单例模式注册,在多线程环境下要注意线程安全问题,虽然 SqlSugar 本身在设计上考虑了多线程场景,但在复杂的业务逻辑中,仍需谨慎处理共享资源的访问。

通过以上对 SqlSugar 结合依赖注入与仓储模式的代码分析和示例展示,相信大家对如何在 C# 项目中高效地进行数据库操作有了更深入的了解。合理运用这些技术,能够让我们的项目在数据访问层面更加稳健和灵活,为整个应用的稳定运行提供有力支持。如果你在实际使用过程中遇到问题或有更好的实践经验,欢迎在评论区交流分享。

上述博客详细讲解了代码的功能与应用。若你觉得内容还需补充,比如增加更多复杂操作示例或优化说明,可随时告知我。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…