更新默认的增删改查仓储对象
增加通用的API返回结果包装
增加IModel转换为查询条件的工具类
IDataModel类增加默认主键
This commit is contained in:
lihanbo 2024-10-16 15:22:09 +08:00
parent e49fff6407
commit de39bba323
15 changed files with 223 additions and 101 deletions

View File

@ -1,40 +0,0 @@
using System;
using System.Reflection;
using LFlow.Base.Interfaces;
namespace LFlow.Base.Default;
/// <summary>
/// 默认的CURD操作
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
public abstract class DefaultCurd<T, K> where T : IModel, IDataModel
{
private readonly IRepo<T, K> _repo;
public DefaultCurd(IRepo<T, K> repo)
{
_repo = repo;
}
public virtual T Add(T model)
{
return _repo.SaveOrUpdate(model, false);
}
public virtual int Delete(K id)
{
return _repo.Delete(id);
}
public virtual T Update(T model)
{
return _repo.SaveOrUpdate(model, true);
}
public virtual T Get(K id)
{
return _repo.Get(id);
}
public virtual List<T> GetAll(int pageIndex, int pageSize, ref int pageTotal)
{
return _repo.GetAll(pageIndex, pageSize, ref pageTotal);
}
public abstract List<T> GetWhere(T WhereObject);
}

View File

@ -1,9 +1,13 @@
using System;
using LFlow.Base.Interfaces; using LFlow.Base.Interfaces;
using LFlow.Base.Utils;
using SqlSugar; using SqlSugar;
namespace LFlow.Base.Default; namespace LFlow.Base.Default;
/// <summary>
/// 默认的增删改查仓储
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IDataModel, new() public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IDataModel, new()
{ {
private readonly ISqlSugarClient _client; private readonly ISqlSugarClient _client;
@ -11,7 +15,13 @@ public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IData
{ {
_client = client; _client = client;
} }
public virtual int Delete(K id) /// <summary>
/// 根据ID删除对象
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public virtual int DeleteById(K id)
{ {
if (Get(id) != null) if (Get(id) != null)
{ {
@ -23,16 +33,32 @@ public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IData
} }
} }
/// <summary>
/// 根据ID获取对象
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual T Get(K id) public virtual T Get(K id)
{ {
return _client.Queryable<T>().InSingle(id); return _client.Queryable<T>().InSingle(id);
} }
/// <summary>
/// 批量查询(分页)
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="pageTotal"></param>
/// <returns></returns>
public List<T> GetAll(int pageIndex, int pageSize, ref int pageTotal) public List<T> GetAll(int pageIndex, int pageSize, ref int pageTotal)
{ {
return _client.Queryable<T>().ToPageList(pageIndex, pageSize, ref pageTotal); return _client.Queryable<T>().ToPageList(pageIndex, pageSize, ref pageTotal);
} }
/// <summary>
/// 报错或是更新对象
/// </summary>
/// <param name="entity"></param>
/// <param name="isUpdate"></param>
/// <returns></returns>
public virtual T SaveOrUpdate(T entity, bool isUpdate) public virtual T SaveOrUpdate(T entity, bool isUpdate)
{ {
if (isUpdate) if (isUpdate)
@ -45,6 +71,22 @@ public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IData
} }
return entity; return entity;
} }
public abstract List<T> Search(T whereObj); /// <summary>
public abstract List<K> WhereSearchId(T whereObj); /// 搜索
/// </summary>
/// <param name="whereObj"></param>
/// <returns></returns>
public virtual List<T> Search(T whereObj)
{
return _client.Queryable<T>().Where(whereObj.ToWhereExp()).ToList();
}
/// <summary>
/// 查找ID
/// </summary>
/// <param name="whereObj"></param>
/// <returns></returns>
public virtual List<K> WhereSearchId(T whereObj)
{
return _client.Queryable<T>().Where(whereObj.ToWhereExp()).Select(x => (K)Convert.ChangeType(x.ID, typeof(K))).ToList();
}
} }

View File

@ -1,4 +1,3 @@
using System;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace LFlow.Base.Interfaces; namespace LFlow.Base.Interfaces;
@ -6,10 +5,7 @@ namespace LFlow.Base.Interfaces;
/// <summary> /// <summary>
/// 基础控制器 /// 基础控制器
/// </summary> /// </summary>
/// <example> /// <example> Route("api/[controller]/[action]") ApiController </example>
/// [Route("api/[controller]/[action]")]
/// [ApiController]
/// </example>
[Route("api/[controller]/[action]")] [Route("api/[controller]/[action]")]
[ApiController] [ApiController]
public abstract class BaseController : ControllerBase, IController public abstract class BaseController : ControllerBase, IController

View File

@ -1,16 +0,0 @@
using System;
using LFlow.Base.Interfaces;
namespace LFlow.Base.BusinessInterface;
/// <summary>
/// Home service interface
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
public interface IHomeService<T, K> : IService<T> where T : IModel
{
T DeleteById(K id);
T GetById(K id);
}

View File

@ -1,8 +0,0 @@
using System;
namespace LFlow.Base.Interfaces.BusinessInterface;
public interface IUserService<T> : IService<T> where T : IModel
{
}

View File

@ -1,5 +1,3 @@
using System;
namespace LFlow.Base.Interfaces; namespace LFlow.Base.Interfaces;
/// <summary> /// <summary>
@ -7,5 +5,11 @@ namespace LFlow.Base.Interfaces;
/// </summary> /// </summary>
public interface IDataModel : IModel public interface IDataModel : IModel
{ {
/// <summary>
/// ID
/// </summary>
public string ID
{
get; set;
}
} }

View File

@ -1,10 +1,9 @@
using System;
namespace LFlow.Base.Interfaces; namespace LFlow.Base.Interfaces;
/// <summary> /// <summary>
/// 模型顶层接口 Service层用 /// 模型顶层接口 Service层用
/// </summary> /// </summary>
public interface IModel public interface IModel
{ {

View File

@ -1,5 +1,3 @@
using System;
namespace LFlow.Base.Interfaces; namespace LFlow.Base.Interfaces;
/// <summary> /// <summary>
@ -20,7 +18,7 @@ public interface IRepo<T, K> where T : IDataModel
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
int Delete(K id); int DeleteById(K id);
/// <summary> /// <summary>
/// 保存与更新 /// 保存与更新
/// </summary> /// </summary>

View File

@ -1,12 +1,17 @@
using System; using LFlow.Base.Utils;
namespace LFlow.Base.Interfaces; namespace LFlow.Base.Interfaces;
/// <summary>
public interface IService<T> where T : IModel /// ·þÎñ½Ó¿Ú
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IService<T> where T : class, IModel, new()
{ {
T GetById(string id); T GetById(string id);
List<T> Search(T whereObj); List<T> Search(T whereObj);
T DeleteById(string id); int DeleteById(string id);
T Save(T entity); T Save(T entity, bool isUpdate);
PagedApiResult<List<T>> GetAll(int pageIndex, int pageSize);
} }

Binary file not shown.

View File

@ -1,11 +1,6 @@
using System.Reflection; using System.Reflection;
using LFlow.Base.Interfaces; using LFlow.Base.Interfaces;
using LFlow.Base.Utils; using LFlow.Base.Utils;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Npgsql.Replication;
using Serilog; using Serilog;
using Serilog.Events; using Serilog.Events;
using SqlSugar; using SqlSugar;
@ -16,6 +11,7 @@ public static class Program
public static void Main(string[] args) public static void Main(string[] args)
{ {
// 先用Serilog的BootstrapLogger
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext() .Enrich.FromLogContext()
@ -23,7 +19,7 @@ public static class Program
.CreateBootstrapLogger(); .CreateBootstrapLogger();
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// 添加到Service中
builder.Services.AddSerilog((services, lc) => lc builder.Services.AddSerilog((services, lc) => lc
.ReadFrom.Configuration(builder.Configuration) .ReadFrom.Configuration(builder.Configuration)
.ReadFrom.Services(services) .ReadFrom.Services(services)
@ -57,7 +53,7 @@ public static class Program
} }
}); });
}); });
// 使用Serilog此处为了修复 `The logger is already frozen` 的问题重新配置Serilog
builder.Host.UseSerilog((context, services, config) => builder.Host.UseSerilog((context, services, config) =>
{ {
config.ReadFrom.Configuration(context.Configuration) config.ReadFrom.Configuration(context.Configuration)
@ -70,6 +66,7 @@ public static class Program
var app = builder.Build(); var app = builder.Build();
app.UseSerilogRequestLogging(options => app.UseSerilogRequestLogging(options =>
{ {
// 配置日志级别
options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Information; options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Information;
}); });
app.MapControllers(); app.MapControllers();
@ -145,7 +142,7 @@ public static class Program
{ {
Log.Logger.Information($"\tFound IModule -> {type.FullName}"); Log.Logger.Information($"\tFound IModule -> {type.FullName}");
var module = Activator.CreateInstance(type) as IModule; var module = Activator.CreateInstance(type) as IModule;
module.ConfigureModule(services); module?.ConfigureModule(services);
} }
} }
} }

View File

@ -0,0 +1,35 @@
namespace LFlow.Base.Utils;
/// <summary>
/// 返回结果包装
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public class ApiResult<T> where T : class, new()
{
public T? Data
{
get; set;
}
public ApiResult()
{
}
public ApiResult(bool success, string message, T data)
{
Success = success;
Message = message;
Data = data;
}
public bool Success
{
get; set;
}
public string? Message
{
get; set;
}
}

View File

@ -0,0 +1,55 @@
using LFlow.Base.Interfaces;
namespace LFlow.Base.Utils;
public static class ObjectToWhereExp
{
/// <summary>
/// 将IModel对象转换为where条件
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static string ToWhereExp(this IModel model)
{
var type = model.GetType();
var properties = type.GetProperties();
var whereExp = " 1=1 ";
foreach (var property in properties)
{
var value = property.GetValue(model);
if (value == null) continue;
if (property.PropertyType == typeof(string))
{
whereExp += $" and {property.Name} like '%{value}%'";
}
else if (property.PropertyType == typeof(DateTime) && value is DateTime dateTime)
{
if (dateTime != default(DateTime))
{
whereExp += $" and {property.Name} like '%{value}%'";
}
}
else if (property.PropertyType.IsEnum)
{
var enumValue = (int)value;
whereExp += $" and {property.Name} = '{enumValue}'";
}
else if (property.PropertyType == typeof(bool) && value is bool flag)
{
if (flag)
{
whereExp += $" and {property.Name} = 1";
}
else
{
whereExp += $" and {property.Name} = 0";
}
}
else if (value != null)
{
whereExp += $" and {property.Name} = '{value}'";
}
}
return whereExp;
}
}

View File

@ -0,0 +1,43 @@
namespace LFlow.Base.Utils;
/// <summary>
/// 返回结果包装 (分页)
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public class PagedApiResult<T> : ApiResult<T> where T : class, new()
{
public new T? Data
{
get; set;
}
public int TotalCount
{
get; set;
}
public int PageIndex
{
get; set;
}
public int PageSize
{
get; set;
}
public PagedApiResult()
{
}
public PagedApiResult(bool success, string message, T data, int totalCount, int pageIndex, int pageSize)
{
Success = success;
Message = message;
Data = data;
TotalCount = totalCount;
PageIndex = pageIndex;
PageSize = pageSize;
}
}

View File

@ -1,11 +1,13 @@
using System;
using LFlow.Base.Interfaces;
namespace LFlow.Base.Utils; namespace LFlow.Base.Utils;
public static class RegisterModule public static class RegisterModule
{ {
public static void RegisterAllModule(this List<Type> types, IServiceCollection services) /// <summary>
/// 注册所有模型
/// </summary>
/// <param name="types"></param>
/// <param name="services"></param>
public static void RegisterAllModel(this List<Type> types, IServiceCollection services)
{ {
foreach (var type in types) foreach (var type in types)
{ {
@ -24,6 +26,11 @@ public static class RegisterModule
} }
} }
} }
/// <summary>
/// 注册所有服务
/// </summary>
/// <param name="types"></param>
/// <param name="services"></param>
public static void RegisterAllService(this List<Type> types, IServiceCollection services) public static void RegisterAllService(this List<Type> types, IServiceCollection services)
{ {
foreach (var type in types) foreach (var type in types)
@ -45,6 +52,11 @@ public static class RegisterModule
} }
} }
} }
/// <summary>
/// 注册所有数据仓库
/// </summary>
/// <param name="types"></param>
/// <param name="services"></param>
public static void RegisterAllRepo(this List<Type> types, IServiceCollection services) public static void RegisterAllRepo(this List<Type> types, IServiceCollection services)
{ {
foreach (var type in types) foreach (var type in types)