开发框架Furion之Winform+SqlSugar

这篇具有很好参考价值的文章主要介绍了开发框架Furion之Winform+SqlSugar。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.开发环境

2.项目搭建

2.1 创建WinFrom主项目

2.2 创建子项目

2.3 实体类库基础类信息配置

2.3.1 Nuget包及项目引用

2.3.2 实体基类创建  

2.4 仓储业务类库基础配置

2.4.1 Nuget包及项目引用

2.4.2 Dtos实体

2.4.3 仓储基类

 2.5 service注册类库基础配置

2.5.1 config配置文件配置

2.5.2 Nuget包及项目引用

 2.5.4 SqlSugar数据库配置

2.5.5 service服务注册

2.6 主项目启动配置

 2.7 示例

2.7.1 codefirst 示例

 2.7.2仓储查询调用示例

3.源代码下载


1.开发环境

  • Visual studio 2022
  • SQLServer
  • .Net6

关于SqlSugar参见教程配置实体 - SqlSugar 5x - .NET果糖网

2.项目搭建

2.1 创建WinFrom主项目

Visual Studio 2022—创建新项目—项目模板中选择 Windows窗体应用

开发框架Furion之Winform+SqlSugar

开发框架Furion之Winform+SqlSugar

 开发框架Furion之Winform+SqlSugar

至此 项目初次创建完成 

开发框架Furion之Winform+SqlSugar

2.2 创建子项目

分别创建项目名称为MyFurion.WFSqlsugar.Model(实体类库)、MyFurion.WFSqlsugar.Setup(service注册类库)、MyFurion.WFSqlsugar.Application(仓储业务类库)三个子项目

开发框架Furion之Winform+SqlSugar

开发框架Furion之Winform+SqlSugar

开发框架Furion之Winform+SqlSugar

项目最终架构

开发框架Furion之Winform+SqlSugar

2.3 实体类库基础类信息配置

2.3.1 Nuget包及项目引用

在MyFurion.WFSqlsugar.Model项目中添加SqlSugarCore

开发框架Furion之Winform+SqlSugar

2.3.2 实体基类创建  

创建基类BaseEntity.cs类

using SqlSugar;
namespace MyFurion.WFSqlsugar.Model
{
    /// <summary>
    /// 实体基类
    /// </summary>
    [SugarIndex("index_{table}_id", nameof(Id), OrderByType.Asc, IsUnique = true)]
    [SugarIndex("index_{table}_createdate", nameof(CreateTime), OrderByType.Asc)]
    [SugarIndex("index_{table}_sort", nameof(SortNum), OrderByType.Asc)]
    [SugarIndex("index_{table}_del", nameof(IsDeleted), OrderByType.Asc)]
    [SugarIndex("index_{table}_orgid", nameof(CreateOrgId), OrderByType.Asc)]
    public class BaseEntity
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public BaseEntity()
        {
            Id = SnowFlakeSingle.Instance.NextId();
            CreateTime = DateTime.Now;
            IsDeleted = true;
        }
        /// <summary>
        /// id
        /// </summary>
        [SugarColumn(IsPrimaryKey =true, ColumnDescription ="主键")]
        public long Id { get; set; }   
        /// <summary>
        /// 创建人id
        /// </summary>
        [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建人id")]
        public string ?CreateUserId { get; set; }
        /// <summary>
        /// 创建人姓名
        /// </summary>
        [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建人姓名")]
        public string? CreateUser { get; set; }
        /// <summary>
        /// 创建时间
        /// </summary>
        [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = false, ColumnDescription = "创建时间")]
        public DateTime CreateTime { get; set; }
        /// <summary>
        /// 修改人id
        /// </summary>
        [SugarColumn(IsOnlyIgnoreInsert = true, IsNullable = true, ColumnDescription = "修改人id")]
        public string? ModifyUserId { get; set; }
        /// <summary>
        /// 修改人姓名
        /// </summary>
        [SugarColumn(IsOnlyIgnoreInsert = true, IsNullable = true, ColumnDescription = "修改人姓名")]
        public string? ModifyUser { get; set; }
        /// <summary>
        /// 修改时间
        /// </summary>
        [SugarColumn(IsOnlyIgnoreInsert =true, IsNullable = true, ColumnDescription = "修改时间")]
        public DateTime? ModifyTime { get; set; }
        /// <summary>
        /// 创建组织机构ID
        /// </summary>
        [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建组织机构ID")]
        public string? CreateOrgId { get; set; }
        /// <summary>
        /// 创建组织机构名称
        /// </summary>
        [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnDescription = "创建组织机构名称")]
        public string? CreateOrgName { get; set; }
        /// <summary>
        /// 排序
        /// </summary>
        [SugarColumn(IsNullable = false, ColumnDescription = "排序")]
        public int SortNum { get; set; }
        /// <summary>
        /// 备注
        /// </summary>
        [SugarColumn(IsNullable = true, ColumnDescription = "备注",ColumnDataType ="nvarchar(max)")]
        public string? Remark { get; set; }
        /// <summary>
        /// 是否删除
        /// </summary>
        [SugarColumn(ColumnDescription = "是否删除")]
        public bool IsDeleted { get; set; }
        /// <summary>
        /// 删除原因
        /// </summary>
        [SugarColumn(ColumnDescription = "删除原因", IsNullable = true)]
        public string? DeleteReason { get; set; }
        /// <summary>
        /// 删除时间
        /// </summary>
        [SugarColumn(IsOnlyIgnoreInsert = true, IsNullable = true, ColumnDescription = "删除时间")]
        public DateTime? DeleteTime { get; set; }
        /// <summary>
        /// 删除人
        /// </summary>
        [SugarColumn(ColumnDescription = "删除人", IsNullable = true)]
        public string? DeleteUser { get; set; }
        /// <summary>
        /// 删除单位
        /// </summary>
        [SugarColumn(ColumnDescription = "删除单位", IsNullable = true)]
        public string? DeleteOrg { get; set; }
        /// <summary>
        /// 多租户ID
        /// </summary>
        [SugarColumn(ColumnDescription = "多租户ID", DefaultValue = "0")]
        public long TenantId { get; set; } = 0;
    }
}

2.4 仓储业务类库基础配置

2.4.1 Nuget包及项目引用

在MyFurion.WFSqlsugar.Application项目中添加Furion、SqlSugar.IOC

添加对MyFurion.WFSqlsugar.Model项目的引用

开发框架Furion之Winform+SqlSugar

开发框架Furion之Winform+SqlSugar

开发框架Furion之Winform+SqlSugar

2.4.2 Dtos实体

项目中创建Dtos文件,用于存放查询条件以及输出信息数据类

首先创建PageResult.cs和PageInputBase.cs,用于仓储基类中使用

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

namespace MyFurion.WFSqlsugar.Application.Dtos
{
    /// <summary>
    /// 分页数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class PageResult<T>
    {
        /// <summary>
        /// 页码
        /// </summary>
        public int PageNo { get; set; }
        /// <summary>
        /// 分页大小
        /// </summary>
        public int PageSize { get; set; }
        /// <summary>
        /// 页总数
        /// </summary>
        public int TotalPage { get; set; }
        /// <summary>
        /// 数据总数
        /// </summary>
        public int TotalRows { get; set; }
        /// <summary>
        /// 记录集合
        /// </summary>
        public List<T> Rows { get; set; } = new();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyFurion.WFSqlsugar.Application.Dtos
{
    public class PageInputBase
    {
        /// <summary>
        /// 搜索值
        /// </summary>
        public  string? SearchValue { get; set; }
        /// <summary>
        /// 当前页码
        /// </summary>
        public  int PageNo { get; set; } = 1;
        /// <summary>
        /// 页码容量
        /// </summary>
        public  int PageSize { get; set; } = 20;
        /// <summary>
        /// 搜索开始时间
        /// </summary>
        public string? SearchBeginTime { get; set; }
        /// <summary>
        /// 搜索结束时间
        /// </summary>
        public  string?SearchEndTime { get; set; }
    }
}

2.4.3 仓储基类

创建仓储基类BaseRepository.cs

using System.Reflection;
using System.Linq.Expressions;
using System.Data;
using MyFurion.WFSqlsugar.Model;
using MyFurion.WFSqlsugar.Application.Dtos;
using SqlSugar;
using SqlSugar.IOC;
using Furion.Logging;
namespace MyFurion.WFSqlsugar.Application
{
    public class BaseRepository<T> : SimpleClient<T> where T : BaseEntity, new()
    {
        public ITenant itenant = null;//多租户事务
        //private readonly ISqlSugarRepository repository;
        public BaseRepository(ISqlSugarClient context = null) : base(context)
        {
            //通过特性拿到ConfigId
            var configId = typeof(T).GetCustomAttribute<TenantAttribute>()?.configId;
            if (configId != null)
            {
                Context = DbScoped.SugarScope.GetConnectionScope(configId);//根据类传入的ConfigId自动选择
            }
            else
            {
                Context = context ?? DbScoped.SugarScope.GetConnectionScope(0);//没有默认db0
            }
            //Context = DbScoped.SugarScope.GetConnectionScopeWithAttr<T>();
            itenant = DbScoped.SugarScope;//设置租户接口
        }

        #region 基础业务
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> Add(T t)
        {
            try
            {
                int rowsAffect = await Context.Insertable(t).IgnoreColumns(true).ExecuteCommandAsync();
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"新增失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> Insert(List<T> t)
        {
            try
            {
                int rowsAffect = await Context.Insertable(t).ExecuteCommandAsync();
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"批量新增失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 插入设置列数据
        /// </summary>
        /// <param name="parm"></param>
        /// <param name="iClumns"></param>
        /// <param name="ignoreNull"></param>
        /// <returns></returns>
        public async Task<bool> Insert(T parm, Expression<Func<T, object>> iClumns = null, bool ignoreNull = true)
        {
            try
            {
                int rowsAffect = await Context.Insertable(parm).InsertColumns(iClumns).IgnoreColumns(ignoreNullColumn: ignoreNull).ExecuteCommandAsync();
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"插入设置列数据失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="ignoreNullColumns"></param>
        /// <returns></returns>
        public async Task<bool> Update(T entity, bool ignoreNullColumns = false)
        {
            try
            {
                int rowsAffect = await Context.Updateable(entity).IgnoreColumns(ignoreNullColumns).ExecuteCommandAsync();
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"更新失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 根据实体类更新指定列 eg:Update(dept, it => new { it.Status });只更新Status列,条件是包含
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="expression"></param>
        /// <param name="ignoreAllNull"></param>
        /// <returns></returns>
        public async Task<bool> Update(T entity, Expression<Func<T, object>> expression, bool ignoreAllNull = false)
        {
            try
            {
                int rowsAffect = await Context.Updateable(entity).UpdateColumns(expression).IgnoreColumns(ignoreAllNull).ExecuteCommandAsync();
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"根据实体类更新指定列失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 根据实体类更新指定列 eg:Update(dept, it => new { it.Status }, f => depts.Contains(f.DeptId));只更新Status列,条件是包含
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="expression"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public async Task<bool> Update(T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where)
        {
            try
            {
                int rowsAffect = await Context.Updateable(entity).UpdateColumns(expression).Where(where).ExecuteCommandAsync();
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"根据实体类更新指定列失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 更新指定列 eg:Update(w => w.NoticeId == model.NoticeId, it => new SysNotice(){ UpdateTime = DateTime.Now, Title = "通知标题" });
        /// </summary>
        /// <param name="where"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public async Task<bool> Update(Expression<Func<T, bool>> where, Expression<Func<T, T>> columns)
        {
            try
            {
                int rowsAffect = await Context.Updateable<T>().SetColumns(columns).Where(where).RemoveDataCache().ExecuteCommandAsync();
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"更新指定列失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 事务 eg:var result = UseTran(() =>{SysRoleRepository.UpdateSysRole(sysRole);DeptService.DeleteRoleDeptByRoleId(sysRole.ID);DeptService.InsertRoleDepts(sysRole);});
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        public bool UseTran(Action action)
        {
            try
            {
                var result = Context.Ado.UseTran(() => action());
                return result.IsSuccess;
            }
            catch (Exception ex)
            {
                Context.Ado.RollbackTran();
                Log.Error($"事务执行失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">主键id</param>
        /// <param name="IsDelete">是否真删除</param>
        /// <returns></returns>
        public async Task<bool> DeleteById(long id, bool IsDelete = false)
        {
            int rowsAffect = 0;
            try
            {
                if (IsDelete)
                {
                    rowsAffect = await Context.Deleteable<T>().In(id).ExecuteCommandAsync();
                }
                else
                {
                    //假删除 实体属性有isdelete或者isdeleted 请升级到5.0.4.9+,(5.0.4.3存在BUG)
                    rowsAffect = await Context.Deleteable<T>().In(id).IsLogic().ExecuteCommandAsync();
                }
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"删除失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 根据查询条件删除
        /// </summary>
        /// <param name="where"></param>
        /// <param name="IsDelete"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByWhere(Expression<Func<T, bool>> where, bool IsDelete = false)
        {
            int rowsAffect = 0;
            try
            {
                if (IsDelete)
                {
                    rowsAffect = await Context.Deleteable<T>().Where(where).ExecuteCommandAsync();
                }
                else
                {
                    //假删除 实体属性有isdelete或者isdeleted 请升级到5.0.4.9+,(5.0.4.3存在BUG)
                    rowsAffect = await Context.Deleteable<T>().Where(where).IsLogic().ExecuteCommandAsync();
                }
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"根据查询条件删除失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 根据id获取数据
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns>泛型实体</returns>
        public async Task<T> GetEntityById(long id)
        {
            return await Context.Queryable<T>().FirstAsync(p => p.Id == id);
        }
        /// <summary>
        /// 数据是否存在
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public async Task<bool> IsExists(Expression<Func<T, bool>> expression)
        {
            return await Context.Queryable<T>().Where(expression).AnyAsync();
        }
        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<T>> GetAll()
        {
            return await Context.Queryable<T>().ToListAsync();
        }
        /// <summary>
        /// 根据查询条件获取数据
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public async Task<List<T>> GetListByWhere(Expression<Func<T, bool>> expression)
        {
            return await Context.Queryable<T>().Where(expression).ToListAsync();
        }
        /// <summary>
        /// 根据查询条件获取数据(动态表格拼接查询条件)
        /// </summary>
        /// <param name="conditions"></param>
        /// <returns></returns>
        public async Task<List<T>> GetListByWhere(List<IConditionalModel> conditions)
        {
            return await Context.Queryable<T>().Where(conditions).ToListAsync();
        }
        /// <summary>
        /// 根据查询条件获取数据
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="orderFiled">排序字段</param>
        /// <param name="orderEnum">排序方式</param>
        /// <returns></returns>
        public async Task<List<T>> GetList(Expression<Func<T, bool>> expression, Expression<Func<T, object>> orderFiled, OrderByType orderEnum = OrderByType.Desc)
        {
            return await Context.Queryable<T>().Where(expression).OrderByIF(orderEnum == OrderByType.Asc, orderFiled, OrderByType.Asc).OrderByIF(orderEnum == OrderByType.Desc, orderFiled, OrderByType.Desc).ToListAsync();
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public PageResult<T> GetPageList(Expression<Func<T, bool>> expression, int pageIndex, int pageSize)
        {
            int totalCount = 0;
            var result = Context.Queryable<T>().Where(expression).ToPageList(pageIndex, pageSize, ref totalCount);
            var pageResult = new PageResult<T>();
            pageResult.Rows = result;
            pageResult.TotalRows = totalCount;
            pageResult.TotalPage = (int)Math.Ceiling(totalCount / (double)pageSize);
            return pageResult;
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<PageResult<T>> GetPageListAsync(Expression<Func<T, bool>> expression, int pageIndex, int pageSize)
        {
            RefAsync<int> totalCount = 0;
            var result = await Context.Queryable<T>().Where(expression).ToPageListAsync(pageIndex, pageSize, totalCount);
            var pageResult = new PageResult<T>();
            pageResult.Rows = result;
            pageResult.TotalRows = totalCount;
            pageResult.TotalPage = (int)Math.Ceiling(totalCount / (double)pageSize);
            return pageResult;
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="orderFiled"></param>
        /// <param name="orderEnum"></param>
        /// <returns></returns>
        public PageResult<T> GetPageList(Expression<Func<T, bool>> expression, int pageIndex, int pageSize, Expression<Func<T, object>> orderFiled, OrderByType orderEnum = OrderByType.Desc)
        {
            int totalCount = 0;
            var result = Context.Queryable<T>().Where(expression).OrderByIF(orderEnum == OrderByType.Asc, orderFiled, OrderByType.Asc).OrderByIF(orderEnum == OrderByType.Desc, orderFiled, OrderByType.Desc)
                .ToPageList(pageIndex, pageSize, ref totalCount);
            var pageResult = new PageResult<T>();
            pageResult.Rows = result;
            pageResult.TotalRows = totalCount;
            pageResult.TotalPage = (int)Math.Ceiling(totalCount / (double)pageSize);
            return pageResult;
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="orderFiled"></param>
        /// <param name="orderEnum"></param>
        /// <returns></returns>
        public async Task<PageResult<T>> GetPageListAsync(Expression<Func<T, bool>> expression, int pageIndex, int pageSize, Expression<Func<T, object>> orderFiled, OrderByType orderEnum = OrderByType.Desc)
        {
            RefAsync<int> totalCount = 0;
            var result = await Context.Queryable<T>().Where(expression).OrderByIF(orderEnum == OrderByType.Asc, orderFiled, OrderByType.Asc).OrderByIF(orderEnum == OrderByType.Desc, orderFiled, OrderByType.Desc)
                .ToPageListAsync(pageIndex, pageSize, totalCount);
            var pageResult = new PageResult<T>();
            pageResult.Rows = result;
            pageResult.TotalRows = totalCount;
            pageResult.TotalPage = (int)Math.Ceiling(totalCount / (double)pageSize);
            return pageResult;
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="orderFiled"></param>
        /// <param name="orderEnum"></param>
        /// <returns></returns>
        public async Task<PageResult<T>> GetOffsetPageListAsync(Expression<Func<T, bool>> expression, int pageIndex, int pageSize, Expression<Func<T, object>> orderFiled, OrderByType orderEnum = OrderByType.Desc)
        {
            RefAsync<int> totalCount = 0;
            var result = await Context.Queryable<T>().Where(expression).OrderByIF(orderEnum == OrderByType.Asc, orderFiled, OrderByType.Asc).OrderByIF(orderEnum == OrderByType.Desc, orderFiled, OrderByType.Desc)
                .ToOffsetPageAsync(pageIndex, pageSize, totalCount);
            var pageResult = new PageResult<T>();
            pageResult.Rows = result;
            pageResult.TotalRows = totalCount;
            pageResult.TotalPage = (int)Math.Ceiling(totalCount / (double)pageSize);
            return pageResult;
        }
        #endregion

        #region 海量业务高性能
        /// <summary>
        /// 新增(对于海量数据并且性能要高的)
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> BulkAdd(T t)
        {
            try
            {
                int rowsAffect = await Context.Storageable(t).ToStorage().BulkCopyAsync();
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"新增失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 批量新增(对于海量数据并且性能要高的)
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> BatchBulkAdd(List<T> t)
        {
            try
            {
                int rowsAffect = await Context.Storageable(t).ToStorage().BulkCopyAsync();
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"批量新增失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 更新(对于海量数据并且性能要高的)
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> BulkUpdate(T entity)
        {
            try
            {
                int rowsAffect = await Context.Storageable(entity).ToStorage().BulkUpdateAsync();
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"更新失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 批量更新(对于海量数据并且性能要高的)
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> BatchBulkUpdate(List<T> t)
        {
            try
            {
                Context.QueryFilter = new QueryFilterProvider();//清空过滤器 否则会出现Parameter '@IsDelete0' must be defined错误
                int rowsAffect = await Context.Storageable(t).ToStorage().BulkUpdateAsync();
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"更新失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 批量更新(对于海量数据并且性能要高的)
        /// </summary>
        /// <param name="t"></param>
        /// <param name="updateColumns"></param>
        /// <returns></returns>
        public async Task<bool> BatchBulkUpdate(List<T> t, string[] updateColumns)
        {
            try
            {
                Context.QueryFilter = new QueryFilterProvider();//清空过滤器 否则会出现Parameter '@IsDelete0' must be defined错误
                int rowsAffect = await Context.Storageable(t).ToStorage().BulkUpdateAsync(updateColumns);
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"更新失败:{ex.Message}");
                return false;
            }
        }
        #endregion

        #region 存储过程
        /// <summary>
        /// 存储过程
        /// </summary>
        /// <param name="procedureName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public async Task<DataTable> ProcedureQuery(string procedureName, object parameters)
        {
            return await Context.Ado.UseStoredProcedure().GetDataTableAsync(procedureName, parameters);
        }
        /// <summary>
        /// 存储过程
        /// </summary>
        /// <param name="procedureName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public async Task<List<T>> ProcedureQueryList(string procedureName, object parameters)
        {
            return await Context.Ado.UseStoredProcedure().SqlQueryAsync<T>(procedureName, parameters);
        }
        #endregion

        #region Fastest
        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> BatchFastestkAdd(List<T> t)
        {
            try
            {
                int rowsAffect = await Context.Fastest<T>().BulkCopyAsync(t);
                return rowsAffect > 0;
            }
            catch (Exception ex)
            {
                Log.Error($"fastest批量新增失败:{ex.Message}");
                return false;
            }
        }
        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> BatchFastestUpdate(List<T> t)
        {
            try
            {
                Context.QueryFilter = new QueryFilterProvider();//清空过滤器 否则会出现Parameter '@IsDelete0' must be defined错误
                int rowsAffect = await Context.Fastest<T>().BulkUpdateAsync(t);
                return rowsAffect >= 0;
            }
            catch (Exception ex)
            {
                Log.Error($"fastest批量更新失败:{ex.Message}");
                return false;
            }
        }
        #endregion
    }
}

 2.5 service注册类库基础配置

2.5.1 config配置文件配置

 首先在主项目MyFurion.WFSqlSugar中新增App.config配置文件,并配置数据库连接配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<appSettings>
		<!--数据库连接-->
		<add key="SqlserverConn" value="Data Source=.;User ID=sa;Password=123456;Initial Catalog=MyFurionTest"/>
		<!--是否需要codeFirst模式-->
		<add key="IsCodeFirst" value="1"/>
	</appSettings>
</configuration>

2.5.2 Nuget包及项目引用

在项目MyFurion.WFSqlsugar.Setup中添加对项目MyFurion.WFSqlsugar.Application的引用

添加Furion.Extras.DatabaseAccessor.SqlSugar、System.Configuration.ConfigurationManager、System.Linq.Dynamic.Core

开发框架Furion之Winform+SqlSugar

开发框架Furion之Winform+SqlSugar

 2.5.4 SqlSugar数据库配置

 创建SqlSugarSet.cs文件,用于对SqlSugar数据库连接的配置数据

using System.Linq.Expressions;
using System.Linq.Dynamic.Core;
using System.Reflection;
using MyFurion.WFSqlsugar.Model;
using SqlSugar;
using SqlSugar.IOC;
using Furion.Logging;
namespace MyFurion.WFSqlsugar.Setup
{
    /// <summary>
    /// 数据库配置
    /// </summary>
    public class SqlSugarSet
    {
        public static void AddSqlsugarSetup()
        {
            string sqlserverConn = System.Configuration.ConfigurationManager.AppSettings["SqlserverConn"].ToString();
            string isCodefirst= System.Configuration.ConfigurationManager.AppSettings["IsCodeFirst"].ToString();
            //string orcaleConn = System.Configuration.ConfigurationManager.AppSettings["OrcaleConn"].ToString();
            List<IocConfig> iocConfigs = new List<IocConfig>()
            {
                new IocConfig (){ ConnectionString=sqlserverConn,ConfigId=0,IsAutoCloseConnection=true,DbType=IocDbType.SqlServer},
                //new IocConfig (){ ConnectionString=orcaleConn,ConfigId=1,IsAutoCloseConnection=true,DbType=IocDbType.Oracle}
            };
            SugarIocServices.AddSqlSugar(iocConfigs);
            SugarIocServices.ConfigurationSugar(db =>
            {
                foreach (var iocItem in iocConfigs)
                {
                    SqlSugarProvider dbClient = db.GetConnection(iocItem.ConfigId);
                    SetQueryFilter(dbClient);
                    //sql执行语句日志
                    dbClient.Aop.OnLogExecuting = (sql, pars) =>
                    {
                        try
                        {
                            Log.Information(SqlProfiler.ParameterFormat(sql, pars));
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"日志错误{ex.StackTrace}");
                        }
                    };
                }
            });
            if (isCodefirst == "1")
            {
                CreateTable(iocConfigs);
            }
        }
        /// <summary>
        /// 创建数据库表 codefirst
        /// </summary>
        private static void CreateTable(List<IocConfig> iocConfigs)
        {
            foreach (var item in iocConfigs)
            {
                string configId = item.ConfigId;
                ISqlSugarClient db = DbScoped.SugarScope.GetConnectionScope(configId);
                db.DbMaintenance.CreateDatabase();//没有数据库的时候创建数据库
                var tableLists = db.DbMaintenance.GetTableInfoList();
                var files = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "MyFurion.WFSqlsugar.Model.dll");
                if (files.Length > 0)
                {
                    Type[] types = Assembly.LoadFrom(files[0]).GetTypes().Where(it => it.BaseType == typeof(BaseEntity)).ToArray();
                    //Type[] types = Assembly.LoadFrom(files[0]).GetTypes().ToArray();
                    foreach (var entityType in types)
                    {
                        //创建数据表
                        string tableName = entityType.GetCustomAttribute<SugarTable>().TableName.ToLower();//根据特性获取表名称
                        var configid = entityType.GetCustomAttribute<TenantAttribute>()?.configId;//根据特性获取租户id
                        configid = configid == null ? "0" : configid.ToString();
                        if (!tableLists.Any(p => p.Name == tableName) && configId == configid.ToString())
                        {
                            //创建数据表包括字段更新
                            db.CodeFirst.InitTables(entityType);
                        }
                    }
                    db.Close();
                }
            }
        }
        /// <summary>
        /// 添加全局过滤器
        /// </summary>
        /// <param name="provider"></param>
        private static void SetQueryFilter(SqlSugarProvider provider)
        {
            //添加全局过滤器
            var files = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "MyFurion.WFSqlsugar.Model.dll");
            if (files.Length > 0)
            {
                Type[] types = Assembly.LoadFrom(files[0]).GetTypes().Where(it => it.BaseType == typeof(BaseEntity)).ToArray();
                foreach (var entityType in types)
                {
                    //string tableName = entityType.GetCustomAttribute<SugarTable>().TableName;//根据特性获取表名称
                    var lambda =DynamicExpressionParser.ParseLambda(new[] { Expression.Parameter(entityType, "it") },
                        typeof(bool), $"{nameof(BaseEntity.IsDeleted)} ==  @0",false);
                    provider.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
                }
            }
            //插入/更新过滤器,用于审计日志
            provider.Aop.DataExecuting = (oldValue, entityInfo) =>
            {
                //新增时操作
                if (entityInfo.OperationType == DataFilterType.InsertByObject)
                {

                }
                //修改时操作        
                if (entityInfo.OperationType == DataFilterType.UpdateByObject)
                {
                    if (entityInfo.PropertyName == "ModifyTime")
                    {
                        entityInfo.SetValue(DateTimeOffset.Now);//修改UpdateTime字段
                    }
                }
            };
        }
    }
}

2.5.5 service服务注册

创建YourStartup.cs,用于Furion框架的相关service的服务注册

using Furion;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace MyFurion.WFSqlsugar.Setup
{
    public class YourStartup : AppStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddRemoteRequest();
            services.AddDatabaseAccessor();//使用数据库配置
            services.AddLogging();//日志服务
            //设置日志
            System.Array.ForEach(new[] { LogLevel.Information, LogLevel.Error }, logLevel =>
            {
                services.AddFileLogging("Logs/{1}-{0:yyyy}-{0:MM}-{0:dd}-{0:HH}.log", options =>
                {
                    options.FileNameRule = fileName => string.Format(fileName, System.DateTime.UtcNow, logLevel.ToString());
                    options.WriteFilter = logMsg => logMsg.LogLevel == logLevel;
                    options.Append = true;
                    //options.MessageFormat = (logMsg) =>
                    //{
                    //    var stringBuilder = new System.Text.StringBuilder();
                    //    stringBuilder.Append(System.DateTime.Now.ToString("o"));
                    //    // 其他的。。。自己组装
                    //    return stringBuilder.ToString();
                    //};
                });
            });
            SqlSugarSet.AddSqlsugarSetup();
        }
    }
}

2.6 主项目启动配置

在项目MyFurion.WFSqlSugar添加对项目MyFurion.WFSqlsugar.Setup的引用

Program.cs中添加代码

 Serve.RunNative(includeWeb: false);//furion框架配置,默认启动

开发框架Furion之Winform+SqlSugar

 2.7 示例

2.7.1 codefirst 示例

创建SystemUser.cs实体类,配置相关表名及租户id

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;

namespace MyFurion.WFSqlsugar.Model
{
    [SugarTable("Sys_User")]
    [Tenant("0")]
    public class SystemUser:BaseEntity
    {
        /// <summary>
        /// 账号
        /// </summary>
        [SugarColumn(Length = 50, ColumnDescription = "账号")]
        public string Account { get; set; }
        /// <summary>
        /// 密码(默认MD5加密)
        /// </summary>
        [SugarColumn(Length = 50, ColumnDescription = "密码")]
        public string Password { get; set; }
        /// <summary>
        /// 昵称
        /// </summary>
        [SugarColumn(Length = 20, IsNullable = true, ColumnDescription = "昵称")]
        public string NickName { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        [SugarColumn(Length = 20, IsNullable = true, ColumnDescription = "姓名")]
        public string UserName { get; set; }
    }
}

启动项目,自动创建数据表,效果展示

开发框架Furion之Winform+SqlSugar

 2.7.2仓储查询调用示例

用户仓储

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Furion.DependencyInjection;
using MyFurion.WFSqlsugar.Model;
using MyFurion.WFSqlsugar.Application.Dtos;
using SqlSugar;
using System.Linq.Expressions;

namespace MyFurion.WFSqlsugar.Application
{
    /// <summary>
    /// 用户仓储业务
    /// </summary>
    public class UserRepository : BaseRepository<SystemUser>, ITransient
    {
        /// <summary>
        /// 账户是否已存在
        /// </summary>
        /// <param name="account"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> IsExists(string account, long id)
        {
            return await Context.Queryable<SystemUser>().AnyAsync(x => x.Account == account && x.Id != id);
        }
        /// <summary>
        /// 分页数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<SystemUser>> GetPageList(PageInputBase input)
        {
            var exp = Expressionable.Create<SystemUser>();
            exp.AndIF(!string.IsNullOrWhiteSpace(input.SearchValue), it => it.UserName.Contains(input.SearchValue)||it.Account.Contains(input.SearchValue));
            Expression<Func<SystemUser, dynamic>> sortPredicate = x => x.CreateTime;
            return await GetPageListAsync(exp.ToExpression(),input.PageNo,input.PageSize, sortPredicate);
        }
    }
}

form页面调用查询

开发框架Furion之Winform+SqlSugar

using Furion;
using MyFurion.WFSqlsugar.Application;
using MyFurion.WFSqlsugar.Application.Dtos;
using MyFurion.WFSqlsugar.Model;

namespace MyFurion.WFSqlSugar
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
           UserRepository userRepository= App.GetService<UserRepository>();
           var data = userRepository.GetPageList(new PageInputBase() { PageNo=1,PageSize=20}).Result;
        }
    }
}

3.源代码下载

WinformFurion: winform +Furion+SqlSugar框架,codefirst模式、包含日志、积累仓储的增删改查等文章来源地址https://www.toymoban.com/news/detail-425568.html

到了这里,关于开发框架Furion之Winform+SqlSugar的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于SqlSugar的开发框架循序渐进介绍(27)-- 基于MongoDB的数据库操作整合

    SqlSugar的开发框架本身主要是基于常规关系型数据库设计的框架,支持多种数据库类型的接入,如SqlServer、MySQL、Oracle、PostgreSQL、SQLite等数据库,非关系型数据库的MongoDB数据库也可以作为扩展整合到开发框架里面,通过基类的继承关系很好的封装了相关的基础操作功能,极大

    2023年04月13日
    浏览(34)
  • 基于SqlSugar的开发框架循序渐进介绍(30)-- 整合客户关系管理系统模块功能

    以前在随笔《Winform开发框架之客户关系管理系统(CRM)的开发总结系列1-界面功能展示 》的几篇随笔中介绍过基于WInform开发框架开发的CRM系统,系统的功能主要也是围绕着客户相关信息来进行管理的,经过一些客户的定制应用,以及框架各种功能的完善,系统也已经很完善了

    2024年02月07日
    浏览(37)
  • 基于SqlSugar的开发框架循序渐进介绍(29)-- 快速构建系统参数管理界面-Vue3+ElementPlus

    在随笔《基于SqlSugar的开发框架循序渐进介绍(28)-- 快速构建系统参数管理界面》中介绍了基于SqlSugar开发框架,构建系统参数管理的后端API部分,以及WInform界面部分内容,本篇随笔介绍基于Vue3+ElementPlus的前端界面开发过程。 系统参数的信息,设计为包含一个大类参数目录

    2024年02月02日
    浏览(45)
  • 基于SqlSugar的开发框架循序渐进介绍(26)-- 实现本地上传、FTP上传、阿里云OSS上传三者合一处理

    在前面介绍的随笔《基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传》中介绍过在文件上传处理的过程中,整合了本地文件上传和基于FTP方式的上传文件的处理整合。本篇随笔继续介绍文件上传的处理,基于选项

    2023年04月10日
    浏览(32)
  • 基于SqlSugar的开发框架循序渐进介绍(31)-- 在查询接口中实现多表联合和单表对象的统一处理

    在一些复杂的业务表中间查询数据,有时候操作会比较复杂一些,不过基于SqlSugar的相关操作,处理的代码会比较简单一些,以前我在随笔《基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理》介绍过基于主表和中间表的联合查询,而往往实际会比这个会复杂

    2024年02月07日
    浏览(38)
  • SqlSugar框架之WPF应用端功能介绍

     WPF应用端是我们《SqlSugar开发框架》多端界面中的一部分,和Winform前端框架、Vue3+ElementPlus前端、UniApp+Thorn移动端,组成一个完整的整体框架,后端服务是基于SqlSugar的基础ORM的.netcore框架,提供Web API服务供各个前端使用,底层支持多种数据库,包括SqlServer、Oracle、Mysql、Po

    2024年02月08日
    浏览(31)
  • C# WinForm —— 项目目录结构

    C# WinForm —— Program类 .sln文件:解决方案文件,提供了解决方案在磁盘中的位置引用,双击可以打开解决方案 1).csproj文件:项目文件,提供了项目文件在磁盘中的引用,双击可以打开项目 2)Program.cs: 程序入口 3)bin文件夹下包含 Debug 和 Release 两个文件夹,分别用于存放

    2024年04月16日
    浏览(31)
  • .NET-4.ORM 常见框架EFcorn、Dapper、SqlSugar、FreeSql 和ADO.NET

    学习参考: 1. .NET 6教程,.Net Core 2022视频教程,杨中科主讲— 以及资料参考 2. 官方文档EF core 常用的语句 3..netmvc https://www.cnblogs.com/1016391912pm/p/12024671.html https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/Querying/Overview 第一个EFCore应用 https://docs.microsoft.com/zh-cn/ef/core/modeli

    2024年02月04日
    浏览(31)
  • win10系统切换到macOS,开发环境与软件资源,目录清单

    1、因为考研自习室或学校图书馆,随身携带游戏本(全能本)受限于 不插电源就不续航和掉性能,以及风扇噪音非常大,以及发热很烫 等问题。 2、所以想考虑给主力机换个mac,目前暂定是买啦 m1pro(10+16)+16g+1t 的版本,因为原来的电脑空间用了非常多,不得不删掉一些东西

    2024年02月15日
    浏览(36)
  • 界面控件DevExpress WinForm——属于WinForm组件的MVVM框架

    DevExpress WinForm拥有180+组件和UI库,能为 Windows Forms 平台创建具有影响力的业务解决方案。 DevExpress WinForm 能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任! 注意 :DevExpress WinForm v22.2已经正式发布,新版

    2023年04月09日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包