sqlsugar -仓储模式番外篇

我是用的是vs2022

IRepositry、Repository仓储层,负责处理数据 就是ADO。net那套东西。

IService、Service 业务服务层,三层架构的BLL。

Model 存放实体类

首先创建者几个目录
在这里插入图片描述
app里面创建webapi项目
其他目录创建类项目
在这里插入图片描述
然后一步一步来,创建model层
在这里插入图片描述
这个是实体,看不懂的去sqlsugar官网
在这里插入图片描述
然后我们开始处理仓储层,创建IBaseRepository类(j接口类),里面添加接口
泛型类约束:
在这里插入图片描述
添加内容:

       /// <summary>
        ///     根据条件查询数据
        /// </summary>
        /// <param name="predicate">条件表达式树</param>
        /// <param name="orderByPredicate">排序字段</param>
        /// <param name="orderByType">排序顺序</param>
        /// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
        /// <returns></returns>
        Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderByPredicate,
            OrderByType orderByType, bool blUseNoLock = false);

然后我们添加BaseRepository类来实现接口

在这里插入图片描述
实现接口:

  public async Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate, bool blUseNoLock = false)
        {
            return blUseNoLock
            ? await DbBaseClient.Queryable<T>().With(SqlWith.NoLock).FirstAsync(predicate)
            : await DbBaseClient.Queryable<T>().FirstAsync(predicate);
        }

到这里仓储层就完结了,接下来我们处理服务层的东西,上面我们说过,可以吧仓储理解为三层,仓储层的DLL层已经弄完了,我们开始弄bll层,bll要调用dll层。
我们创建IBaseServices接口类:
这里的约束里面是只有class,没有new(),说明继承这个接口类的时候不用构造函数
在这里插入图片描述
然后在里面添加接口:


            /// <summary>
            ///     根据条件查询数据
            /// </summary>
            /// <param name="predicate">条件表达式树</param>
            /// <param name="orderByPredicate">排序字段</param>
            /// <param name="orderByType">排序顺序</param>
            /// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
            /// <returns></returns>
            Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderByPredicate,
                OrderByType orderByType, bool blUseNoLock = false);

然后我们添加BaseServices类来实现IBaseServices的接口

public IBaseRepository BaseDal;要明白这个就是用来调用仓储层的接口的,server层调用Repository的方法,Repository的方法来访问数据库,可以这么理解
在这里插入图片描述

接口实现:

    public async Task<T> QueryByClauseAsync(Expression<Func<T, bool>> predicate,
            Expression<Func<T, object>> orderByPredicate, OrderByType orderByType, bool blUseNoLock = false)
        {
            return await BaseDal.QueryByClauseAsync(predicate, orderByPredicate, orderByType, blUseNoLock);
        }

仓储模式基本算搞定了。

开始做数据展示了
我们还是先创建仓储层的接口IOPS_Monitor_Item_ResultRepository类,然后继承IBaseServices,这样我们的IOPS_Monitor_Item_ResultRepository接口类就有了IBaseServices接口类的所有接口的东西

在这里插入图片描述

using Model.Entites.System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IRepository
{
//上面的截图中有 IBaseRepository<T> where T : class, new()约束,意思是:T可以传任何实体类进来,class限定只能类来继承,new()指定继承累必须有构造函数,而我这里没有,是省略了或者说C#是默认给你隐藏了,因为你不需要在构造函数里面干啥事
    public interface IOPS_Monitor_Item_ResultRepository : IBaseRepository<OPS_Monitor_Item_Result>
    {
    }
}

我们上面写了IOPS_Monitor_Item_ResultRepository接口,就要实现接口:

using IRepository;
using Model.Entites.System;
using Repository.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Repository
{
//这里我们已经继承了BaseRepository接口,实际上如果我们把所有的接口都在BaseRepository里面实现了,就不需要在继承IOPS_Monitor_Item_ResultRepository这个接口了
//,之所以还要继承是为了有面这个实体有需要实现的特殊逻辑,可以单独写在这里面方便扩展
    public class OPS_Monitor_Item_ResultRepository:BaseRepository<OPS_Monitor_Item_Result>, IOPS_Monitor_Item_ResultRepository
    {
        public OPS_Monitor_Item_ResultRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
        {
             
        }
    }
}

仓储层完成了(对应的三层DLL)
那我们开始弄服务层(bll)
老样子创建服务层IOPS_Monitor_Item_ResultServices接口:

using Model.Entites.System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IServices
{
    public interface IOPS_Monitor_Item_ResultServices:IBaseServices<OPS_Monitor_Item_Result>
    {
    }
}

实现服务层OPS_Monitor_Item_ResultServices接口:

using IRepository;
using IServices;
using Model.Entites.System;
using Repository.UnitOfWork;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Services
{
    public class OPS_Monitor_Item_ResultServices:BaseServices<OPS_Monitor_Item_Result>, IOPS_Monitor_Item_ResultServices
    {
        //定义的事务调用
        private readonly IUnitOfWork _unitOfWork;
        private readonly IOPS_Monitor_Item_ResultRepository _db;
        public OPS_Monitor_Item_ResultServices(IUnitOfWork unitOfWork, IOPS_Monitor_Item_ResultRepository db )
        {
            _db=db;
           // BaseDal 这个地方是不是很熟悉,他就是BaseServices类中的 public IBaseRepository<T> BaseDal
           //这个东西,这个就是给你调用仓储层的方法用的
            BaseDal = db;
            _unitOfWork =unitOfWork; 
        }
    }
}

这个仓储的第一个模型搞完,开始调用,创建要给控制器:

using IServices;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Model.Entites.System;

namespace WEBAPI6._0.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class MonitorController : ControllerBase
    {
    //用哪个接口,你就在构造函数里面去初始化赋值
        private readonly IOPS_Monitor_Item_ResultServices _OPS_Monitor_Item_Result; 

        public MonitorController(IOPS_Monitor_Item_ResultServices OPS_Monitor_Item_Result )
        {
            _OPS_Monitor_Item_Result = OPS_Monitor_Item_Result; 
        }


        [HttpPost]
        public async Task<List<OPS_Monitor_Item_Result>> ceshi()
        {

            string id = "168672";
            string datetimestring = "2022-05-01";
            List<OPS_Monitor_Item_Result> result= await _OPS_Monitor_Item_Result.QueryListByClauseAsync(p=>p.operation_id== id&&p.monitoring_time>=Convert.ToDateTime(datetimestring),p=>p.monitoring_time,SqlSugar.OrderByType.Desc);

            return result;
        }

     

    }
}

这里还有 数据库链接服务,autofac的ioc没写
我只直接贴代码不想写了:
SqlSugarSetup类

using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using SqlSugar.IOC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Net.Configuration
{
    public static class SqlSugarSetup
    {
        public static void AddSqlSugarSetup(this IServiceCollection services) {
            if (services == null) throw new ArgumentNullException(nameof(services));
           
            //注入 ORM
            SugarIocServices.AddSqlSugar(new IocConfig()
            {
                //数据库连接,这个地方我做了集成,你使用的时候可以直接链接字符串贴上来就能用
                ConnectionString = AppSettingsConstVars.DbSqlConnection,
                //判断数据库类型,这里可以写死  DbType ="SqlServer"
                DbType = AppSettingsConstVars.DbDbType == IocDbType.MySql.ToString() ? IocDbType.MySql : IocDbType.SqlServer,
                //是否开启自动关闭数据库连接-//不设成true要手动close
                IsAutoCloseConnection = true,
            });

            //设置参数
            services.ConfigurationSugar(db =>
            {
                db.CurrentConnectionConfig.InitKeyType = InitKeyType.Attribute;
                //db.CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices()
                //{
                //    //判断是否开启redis设置二级缓存方式
                //    DataInfoCacheService = AppSettingsConstVars.RedisUseCache ? (ICacheService)new SqlSugarRedisCache() : new SqlSugarMemoryCache()
                //};

                //执行SQL 错误事件,可监控sql(暂时屏蔽,需要可开启)
                //db.Aop.OnLogExecuting = (sql, p) =>
                //{
                //    NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.Other, "SqlSugar执行SQL错误事件打印Sql", sql);
                //};

                //执行SQL 错误事件
                db.Aop.OnError = (exp) =>
                {
                   // NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.Other, "SqlSugar", "执行SQL错误事件", exp);
                };

                //设置更多连接参数
                //db.CurrentConnectionConfig.XXXX=XXXX
                //db.CurrentConnectionConfig.MoreSetting=new MoreSetting(){}
                //读写分离等都在这儿设置
            });
        }



    }
}

ioc:
AutofacModuleRegister

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac; 
using System.Reflection;

namespace Net.Configuration.AutoFac
{
    public class AutofacModuleRegister : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {

            var basePath = AppContext.BaseDirectory;

          

            var servicesDllFile1 = Path.Combine(basePath, "CoreCms.Net.Services.dll");
            var repositoryDllFile1 = Path.Combine(basePath, "CoreCms.Net.Repository.dll");



            var basePath1 = Directory.GetCurrentDirectory();
            DirectoryInfo info = new DirectoryInfo(basePath1);
            string repositoryDllFile = info.Parent.FullName+ "\\Repository\\bin\\Debug\\net6.0\\Repository.dll";
            string servicesDllFile = info.Parent.FullName + "\\Services\\bin\\Debug\\net6.0\\Services.dll";
          
            #region 带有接口层的服务注入
 

            if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
            {
                var msg = "Repository.dll和Services.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。";
                throw new Exception(msg);
            }

            var basePath = AppContext.BaseDirectory;
            var dllName1 = "Repository.dll";
            #region 带有接口层的服务注入

            var servicesDllFile = Path.Combine(basePath, "Services.Services.dll");
            var repositoryDllFile = Path.Combine(basePath, "Repository.Repository.dll");

            if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
            {
                var msg = "Repository.dll和Services.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。";
                throw new Exception(msg);
            }

            // AOP 开关,如果想要打开指定的功能,只需要在 appsettigns.json 对应对应 true 就行。
            //var cacheType = new List<Type>();
            //if (AppSettingsConstVars.RedisConfigEnabled)
            //{
            //    builder.RegisterType<RedisCacheAop>();
            //    cacheType.Add(typeof(RedisCacheAop));
            //}
            //else
            //{
            //    builder.RegisterType<MemoryCacheAop>();
            //    cacheType.Add(typeof(MemoryCacheAop));
            //}

            // 获取 Service.dll 程序集服务,并注册
            var assemblysServices = Assembly.LoadFrom(servicesDllFile);
            //支持属性注入依赖重复
            builder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces().InstancePerDependency()
                .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

            // 获取 Repository.dll 程序集服务,并注册
            var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
            //支持属性注入依赖重复
            builder.RegisterAssemblyTypes(assemblysRepository).AsImplementedInterfaces().InstancePerDependency()
                .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);


            // 获取 Service.dll 程序集服务,并注册
            //var assemblysServices = Assembly.LoadFrom(servicesDllFile);
            //builder.RegisterAssemblyTypes(assemblysServices)
            //    .AsImplementedInterfaces()
            //    .InstancePerDependency()
            //    .PropertiesAutowired()
            //    .EnableInterfaceInterceptors()//引用Autofac.Extras.DynamicProxy;
            //    .InterceptedBy(cacheType.ToArray());//允许将拦截器服务的列表分配给注册。

             获取 Repository.dll 程序集服务,并注册
            //var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
            //builder.RegisterAssemblyTypes(assemblysRepository)
            //    .AsImplementedInterfaces()
            //    .PropertiesAutowired()
            //    .InstancePerDependency();


            #endregion

        }
    }
}

随后在program中添加:

//添加本地路径获取支持 
builder.Services.AddSingleton(new AppSettingsHelper());
//添加数据库连接SqlSugar注入支持
builder.Services.AddSqlSugarSetup( );
//配置跨域(CORS)
builder.Services.AddCorsSetup();
 
//自定义ioc使用autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
 builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
    builder.RegisterModule(new AutofacModuleRegister());
});

就可以跑起来了,记得生成数据库和数据,文中的unitOfWork和_unitOfWork可以删了,刚开始用不上的

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
仓储模式是一种常见的设计模式,用于将数据访问逻辑与业务逻辑分离。在 C# 中,可以使用 SqlSugar 实现仓储模式。 首先,需要定义一个接口,用于声明对数据访问的操作: ```csharp public interface IRepository<T> { IEnumerable<T> GetAll(); T GetById(int id); void Add(T entity); void Update(T entity); void Delete(int id); } ``` 然后,实现这个接口: ```csharp public class Repository<T> : IRepository<T> where T : class, new() { private readonly SqlSugarClient _db; public Repository(SqlSugarClient db) { _db = db; } public IEnumerable<T> GetAll() { return _db.Queryable<T>().ToList(); } public T GetById(int id) { return _db.Queryable<T>().InSingle(id); } public void Add(T entity) { _db.Insertable(entity).ExecuteCommand(); } public void Update(T entity) { _db.Updateable(entity).ExecuteCommand(); } public void Delete(int id) { _db.Deleteable<T>().In(id).ExecuteCommand(); } } ``` 在这个实现中,使用了 SqlSugar 提供的 Queryable、Insertable、Updateable 和 Deleteable 方法来执行对数据库的操作。 最后,可以在业务逻辑中使用这个仓储来访问数据: ```csharp public class UserService { private readonly IRepository<User> _userRepository; public UserService(IRepository<User> userRepository) { _userRepository = userRepository; } public IEnumerable<User> GetAllUsers() { return _userRepository.GetAll(); } public User GetUserById(int id) { return _userRepository.GetById(id); } public void AddUser(User user) { _userRepository.Add(user); } public void UpdateUser(User user) { _userRepository.Update(user); } public void DeleteUser(int id) { _userRepository.Delete(id); } } ``` 这样,就可以将数据访问逻辑和业务逻辑分离,使代码更加清晰和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值