概述

项目是用的 NET6 webapi搭建一个前后端分离的后端管理框架,项目分为:表示层、业务层、数据访问层、数据存储层。

Common:公共组件层,存放一些公共的方法。Model:实体Model数据层,Enity文件夹中,存放的是项目的数据库表实体类,VeiwModel文件夹,是存放的DTO实体类,根据接口需要接收的数据和返回的数据。IRepository和 Repository :repository就是一个管理数据持久层的,它负责数据的CRUD。IServices和 Service:业务逻辑层,它主要是调用Repository层。

swagger

为了方便接口的查看和调试,本项目用swagger组件。
在.net core webapi 6.0是自带swagger功能的,以前在.net framework时代 swagger是要在项目下单独安装组件和配置后才具有的一个功能。项目启动后,在站点默认路径为:https://localhost:7182/swagger/index.html 这里就是swagger的首页。 

NLog

1.Nuget 引入:
  NLog
  NLog.Web.AspNetCore
  NLog.Database(写入数据库使用)

2.创建nlog.config

<?xml version="1.0" encoding="utf-8" ?>
<!--internalLogLevel 记录Nlog自身日志级别,正式环境改为Error
autoReload="true" nlog.config配置文件修改,程序将会重新读取配置文件,也就是自动再配置
-->
<!--internalLogLevel="Error"-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Info"
internalLogFile="${basedir}/internal-nlog.txt">
<!-- 启用.net core的核心布局渲染器 -->
<extensions>
<add assembly="NLog.Web.AspNetCore" />
<!--写入数据库使用-->
<!--<add assembly="NLog.Database" />-->
</extensions>
<!-- 写入日志的目标配置 -->
<targets>
<!-- all : write logs to file -->
<target xsi:type="File" name="all" fileName="${basedir}/logs/all-${shortdate}.log"
layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} " />
<!-- debug : write logs to file -->
<target xsi:type="File" name="debug" fileName="${basedir}/logs/debug-${shortdate}.log"
layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} " />
<!-- info : write logs to file -->
<target xsi:type="File" name="info" fileName="${basedir}/logs/info-${shortdate}.log"
layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} |url: ${aspnet-request-url} |action: ${aspnet-mvc-action}" />
<!-- error : write logs to file -->
<target xsi:type="File" name="error" fileName="${basedir}/logs/error-${shortdate}.log"
layout="${longdate} |${uppercase:${level}}|${logger}|${message} ${exception} |url: ${aspnet-request-url} |action: ${aspnet-mvc-action}" /> </targets>
<!-- 映射规则 -->
<rules>
<!-- 将宿主生命周期消息输出到控制台目标,以更快地进行启动检测 -->
<!--<logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />--> <!-- 全部 -->
<!--<logger name="*" minlevel="Trace" maxlevel="Fatal" writeTo="all" />--> <!-- 跳过不重要的微软日志 -->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="System.Net.Http.*" maxlevel="Info" final="true" /> <!-- 调试 -->
<logger name="*" levels="Trace,Debug" writeTo="debug" />
<!-- 信息、警告 -->
<logger name="*" levels="Info,Warn" writeTo="info" />
<!-- 错误、致命错误 -->
<logger name="*" levels="Error,Fatal" writeTo="error" />
</rules>
</nlog>

3.注入Nlog

using NLog;
using NLog.Web; var logger = NLog.LogManager.Setup().LoadConfigurationFromFile("ConfigFile/NLog.config").GetCurrentClassLogger(); try
{ IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build(); var builder = WebApplication.CreateBuilder(args); builder.Services.AddSingleton(new AppSettingsHelper(configuration)); #region NLog配置
builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information);
builder.Host.UseNLog();
#endregion // Add services to the container. builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} app.UseAuthorization(); app.MapControllers(); app.Run(); }
catch (Exception ex)
{
logger.Error(ex, "由于异常而停止程序");
throw;
}
finally
{
LogManager.Shutdown();
}

4.使用

[HttpGet]
public ActionResult<string> test(string username)
{ _logger.LogInformation("测试日志组件"); _logger.LogError($"LogError 方法"); return username + " ,你好!"; }

统一处理返回值和异常

1.定义统一的返回类

    public enum ResultStatus
{
[Description("请求成功")]
Success = 1,
[Description("请求失败")]
Fail = 0,
[Description("请求异常")]
Error = -1
} public class ResponseResult<TEntity>
{
/// <summary>
/// 状态结果
/// </summary>
public ResultStatus Status { get; set; } = ResultStatus.Success; private string? _msg; /// <summary>
/// 消息描述
/// </summary>
public string? Message
{
get
{
// 如果没有自定义的结果描述,则可以获取当前状态的描述
return !string.IsNullOrEmpty(_msg) ? _msg : EnumExtension.GetDescription(Status);
}
set
{
_msg = value;
}
} /// <summary>
/// 返回结果
/// </summary>
public TEntity Data { get; set; } /// <summary>
/// 成功状态返回结果
/// </summary>
/// <param name="result">返回的数据</param>
/// <returns></returns>
public static ResponseResult<TEntity> SuccessResult(TEntity data)
{
return new ResponseResult<TEntity> { Status = ResultStatus.Success, Data = data };
} /// <summary>
/// 失败状态返回结果
/// </summary>
/// <param name="code">状态码</param>
/// <param name="msg">失败信息</param>
/// <returns></returns>
public static ResponseResult<TEntity> FailResult(string? msg = null)
{
return new ResponseResult<TEntity> { Status = ResultStatus.Fail, Message = msg };
} /// <summary>
/// 异常状态返回结果
/// </summary>
/// <param name="code">状态码</param>
/// <param name="msg">异常信息</param>
/// <returns></returns>
public static ResponseResult<TEntity> ErrorResult(string? msg = null)
{
return new ResponseResult<TEntity> { Status = ResultStatus.Error, Message = msg };
} /// <summary>
/// 自定义状态返回结果
/// </summary>
/// <param name="status"></param>
/// <param name="result"></param>
/// <returns></returns>
public static ResponseResult<TEntity> Result(ResultStatus status, TEntity data, string? msg = null)
{
return new ResponseResult<TEntity> { Status = status, Data = data, Message = msg };
} /// <summary>
/// 隐式将TEntity转化为ResponseResult<TEntity>
/// </summary>
/// <param name="value"></param>
public static implicit operator ResponseResult<TEntity>(TEntity value)
{
return new ResponseResult<TEntity> { Data = value };
} }

2.添加异常过滤器

public class ResultWrapperFilter : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var actionWrapper = controllerActionDescriptor?.MethodInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault();
var controllerWrapper = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttributes(typeof(NoWrapperAttribute), false).FirstOrDefault();
//如果包含NoWrapperAttribute则说明不需要对返回结果进行包装,直接返回原始值
if (actionWrapper != null || controllerWrapper != null)
{
return;
} //根据实际需求进行具体实现
var rspResult = new ResponseResult<object>();
if (context.Result is ObjectResult)
{
var objectResult = context.Result as ObjectResult;
if (objectResult?.Value == null)
{
rspResult.Status = ResultStatus.Fail;
rspResult.Message = "未找到资源";
context.Result = new ObjectResult(rspResult);
}
else
{
//如果返回结果已经是ResponseResult<T>类型的则不需要进行再次包装了
if (objectResult.DeclaredType.IsGenericType && objectResult.DeclaredType?.GetGenericTypeDefinition() == typeof(ResponseResult<>))
{
return;
}
rspResult.Data = objectResult.Value;
context.Result = new ObjectResult(rspResult);
}
return;
}
}
}

  

    public class GlobalExceptionFilter : IExceptionFilter
{
private readonly ILogger<GlobalExceptionFilter> _logger;
public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
{
_logger = logger;
} public void OnException(ExceptionContext context)
{
//异常返回结果包装
var rspResult = ResponseResult<object>.ErrorResult(context.Exception.Message);
//日志记录
_logger.LogError(context.Exception, context.Exception.Message);
context.ExceptionHandled = true;
context.Result = new InternalServerErrorObjectResult(rspResult);
} public class InternalServerErrorObjectResult : ObjectResult
{
public InternalServerErrorObjectResult(object value) : base(value)
{
StatusCode = 500;
}
}
}

3.注入

    builder.Services.AddControllers(options =>
{
options.Filters.Add<ResultWrapperFilter>();
options.Filters.Add<GlobalExceptionFilter>();
});

4.使用

public class TestController : ApiControllerBase
{
[HttpGet()]
public ResponseResult<string> Get()
{
string datas = "测试统一返回消息"; //throw new Exception("测试异常是否被记录"); Convert.ToInt32("aaaaaaa"); return ResponseResult<string>.SuccessResult(datas) ;
}
}

Autofac

1.Nuget引入:
Autofac
Autofac.Extensions.DependencyInjection

2.定义Module,方便对注入服务进行管理

public class AutoFacManager : Autofac.Module
{ //重写Autofac管道Load方法,在这里注册注入
protected override void Load(ContainerBuilder builder)
{
//程序集注入业务服务
var IAppServices = Assembly.Load("TanYongJun.Repository");
var AppServices = Assembly.Load("TanYongJun.Service");
//根据名称约定(服务层的接口和实现均以Service结尾),实现服务接口和服务实现的依赖
builder.RegisterAssemblyTypes(IAppServices).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces();
builder.RegisterAssemblyTypes(AppServices).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces();
}
}

  注意:程序集的命名必须规范,否则可能读取不到 对应的数据集从而报错。

3.注入Autofac

 builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new AutoFacManager());
});

AutoMapper

1.Nuget引入:
AutoMapper
AutoMapper.Extensions.Microsoft.Dependencylnjection

2.定义Profile

    public class CustomAutoMapper : Profile
{
/// <summary>
/// 配置构造函数,用来创建关系映射
/// </summary>
public CustomAutoMapper()
{//这里写映射规则 //把 Student 映射到 StudentDTO
CreateMap<Student, StudentDTO>(); CreateMap<SysUser, SysUserDTO>();
}
}

3.注入

//AutoMapper
builder.Services.AddAutoMapper(typeof(CustomAutoMapper));

4.使用

    public class TestController : ApiControllerBase
{
private readonly IMapper _mapper; public TestController(IMapper mapper)
{
_mapper = mapper;
} [HttpGet()]
public ResponseResult<StudentDTO> Get()
{ var student = new Student() { Id = 1, RealName = "tanyongjun", Age = 21, Sex = 1, Remark = "" };
var studentDto = _mapper.Map<StudentDTO>(student); return ResponseResult<StudentDTO>.SuccessResult(studentDto); } }

EFCore

1.Nuget引入:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools

2. 创建上下文类

public class EFCoreContext : DbContext
{ public EFCoreContext(DbContextOptions<EFCoreContext> options) : base(options)
{ } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new SysUserEntityTypeConfiguration()); #region 添加初始化数据 //modelBuilder.Entity<T>().HasData(new T { ..... }); #endregion base.OnModelCreating(modelBuilder);
} }

  

3. 分别在IRepository和Repository项目下,新建IBaseRepository和BaseRepository,具体代码如下:

public interface IBaseRepository<TEntity> where TEntity : class
{
#region 添加
Task<TEntity> Add(TEntity entity); Task<int> Add(List<TEntity> listEntity); #endregion #region 修改
Task<bool> Update(TEntity entity); Task<bool> Update(TEntity model, params string[] propertyNames); Task<bool> Update(TEntity model, Expression<Func<TEntity, bool>> whereLambda, params string[] modifiedPropertyNames); #endregion #region 删除 Task<bool> Delete(TEntity entity); Task<bool> DeleteBy(Expression<Func<TEntity, bool>> delWhere); #endregion #region 查询 Task<TEntity> QueryBy(Expression<Func<TEntity, bool>> whereLambda); Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereLambda); Task<List<TEntity>> Query(); Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true); Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int top, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true); Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true); Task<PageModel<TEntity>> QueryPage<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true); #endregion #region 执行存储过程 Task<List<TEntity>> Query(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text); Task<int> Execute(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text); #endregion ORTHER
}

  

public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class, new()
{
private EFCoreContext _db; public BaseRepository(EFCoreContext mydbcontext)
{
this._db = mydbcontext as EFCoreContext;
} #region 添加
/// <summary>
/// 新增实体
/// </summary>
/// <param name="entity">实体类</param>
/// <returns></returns>
public async Task<TEntity> Add(TEntity entity)
{
_db.Set<TEntity>().Add(entity);
await _db.SaveChangesAsync();
return entity;
} /// <summary>
/// 批量新增实体
/// </summary>
/// <param name="listEntity">实体集合</param>
/// <returns>影响行数</returns>
public async Task<int> Add(List<TEntity> listEntity)
{
await _db.Set<TEntity>().AddRangeAsync(listEntity);
return await _db.SaveChangesAsync();
} #endregion #region 修改
/// <summary>
/// 更新实体数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<bool> Update(TEntity entity)
{
_db.Set<TEntity>().Update(entity);
return await _db.SaveChangesAsync() > 0;
} /// <summary>
/// 更新实体的指定字段
/// </summary>
/// <param name="model"></param>
/// <param name="propertyNames"></param>
/// <returns></returns>
public async Task<bool> Update(TEntity model, params string[] propertyNames)
{
EntityEntry entry = _db.Entry<TEntity>(model);
entry.State = EntityState.Unchanged;
foreach (string propertyName in propertyNames)
{
entry.Property(propertyName).IsModified = true;
}
return await _db.SaveChangesAsync() > 0;
} /// <summary>
/// 根据表达式查询出来的结果集,批量更新指定字段
/// </summary>
/// <param name="model"></param>
/// <param name="whereLambda"></param>
/// <param name="modifiedPropertyNames"></param>
/// <returns></returns>
public async Task<bool> Update(TEntity model, Expression<Func<TEntity, bool>> whereLambda, params string[] modifiedPropertyNames)
{
List<TEntity> listModifing = _db.Set<TEntity>().Where(whereLambda).ToList();
Type t = typeof(TEntity);
List<PropertyInfo> propertyInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
Dictionary<string, PropertyInfo> dicPropertys = new Dictionary<string, PropertyInfo>();
propertyInfos.ForEach(p =>
{
if (modifiedPropertyNames.Contains(p.Name))
{
dicPropertys.Add(p.Name, p);
}
});
foreach (string propertyName in modifiedPropertyNames)
{
if (dicPropertys.ContainsKey(propertyName))
{
PropertyInfo proInfo = dicPropertys[propertyName];
object newValue = proInfo.GetValue(model, null);
foreach (TEntity item in listModifing)
{
proInfo.SetValue(item, newValue, null);
}
}
} return await _db.SaveChangesAsync() > 0;
} #endregion #region 删除 /// <summary>
/// 根据实体删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<bool> Delete(TEntity entity)
{
_db.Set<TEntity>().Attach(entity);
_db.Set<TEntity>().Remove(entity);
return await _db.SaveChangesAsync() > 0;
} /// <summary>
/// 根据表达式条件删除
/// </summary>
/// <param name="delWhere"></param>
/// <returns></returns>
public async Task<bool> DeleteBy(Expression<Func<TEntity, bool>> delWhere)
{ List<TEntity> listDeleting = _db.Set<TEntity>().Where(delWhere).ToList();
listDeleting.ForEach(u =>
{
_db.Set<TEntity>().Attach(u);
_db.Set<TEntity>().Remove(u);
});
return await _db.SaveChangesAsync() > 0;
} #endregion #region 查询 /// <summary>
/// 根据表达式查询,返回单个实体
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public async Task<TEntity> QueryBy(Expression<Func<TEntity, bool>> whereLambda)
{
return await _db.Set<TEntity>().Where(whereLambda).AsNoTracking().FirstOrDefaultAsync();
}
/// <summary>
/// 根据表达式查询,返回实体列表
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public async Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereLambda)
{
return await _db.Set<TEntity>().Where(whereLambda).AsNoTracking().ToListAsync();
} /// <summary>
/// 返回实体所有列表
/// </summary>
/// <returns></returns>
public async Task<List<TEntity>> Query()
{
return await _db.Set<TEntity>().AsNoTracking().ToListAsync();
} #endregion #region 排序查询
/// <summary>
/// 根据表达式查询,返回实体集合,并按指定排序
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="orderLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public async Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true)
{
if (isAsc)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda).AsNoTracking().ToListAsync();
}
} /// <summary>
/// 根据表达式查询,返回实体集合,并按指定排序返回指定行数
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="top"></param>
/// <param name="orderLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public async Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int top, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true)
{
if (isAsc)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda).Take(top).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda).Take(top).AsNoTracking().ToListAsync();
}
} #endregion #region 分页查询 /// <summary>
/// 按表达式分页查询,并按指定排序,返回实体集合
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="orderByLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public async Task<List<TEntity>> Query<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true)
{
if (isAsc)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderByLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderByLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
} /// <summary>
/// 按表达式分页查询,并按指定排序,返回分页实体
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="orderByLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public async Task<PageModel<TEntity>> QueryPage<TKey>(Expression<Func<TEntity, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true)
{
var rowCount = await _db.Set<TEntity>().Where(whereLambda).CountAsync(); int pageCount = (int)(Math.Ceiling(rowCount/ Convert.ToDouble( pageSize))); List<TEntity> list;
if (isAsc)
{
list = await _db.Set<TEntity>().OrderBy(orderByLambda).Where(whereLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
else
{
list = await _db.Set<TEntity>().OrderByDescending(orderByLambda).Where(whereLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
} return new PageModel<TEntity>() { DataCount = rowCount, PageCount = pageCount, Page = pageIndex, PageSize = pageSize, DataList = list };
} #endregion #region 存储过程 /// <summary>
/// 执行存储过程 exec Proc_ @name,返回实体集合
/// </summary>
/// <param name="sql"></param>
/// <param name="parms"></param>
/// <param name="cmdType"></param>
/// <returns></returns>
public async Task<List<TEntity>> Query(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text)
{
if (cmdType == CommandType.StoredProcedure)
{
StringBuilder paraNames = new StringBuilder();
foreach (var sqlPara in parms)
{
paraNames.Append($" @{sqlPara},");
}
sql = paraNames.Length > 0 ? $"exec {sql} {paraNames.ToString().Trim(',')}" : $"exec {sql} ";
} return await _db.Set<TEntity>().FromSqlRaw(sql).ToListAsync(); } /// <summary>
/// 执行存储过程 exec Proc_ @name,返回影响行数
/// </summary>
/// <param name="sql"></param>
/// <param name="parms"></param>
/// <param name="cmdType"></param>
/// <returns></returns>
public async Task<int> Execute(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text)
{
if (cmdType == CommandType.StoredProcedure)
{
StringBuilder paraNames = new StringBuilder();
foreach (var sqlPara in parms)
{
paraNames.Append($" @{sqlPara},");
}
sql = paraNames.Length > 0 ?
$"exec {sql} {paraNames.ToString().Trim(',')}" :
$"exec {sql} ";
} int ret = await _db.Database.ExecuteSqlRawAsync(sql, parms.ToArray());
return 0;
} #endregion }

 BaseRepository中主要是实现了一些基础的CURD操作,并且封装了一些常用的数据库操作。 

跨域

appsettings.json

appsettings.json中主要是存放一些项目中配置参数,和以前的webconfig文件。为了方便这里写一个读取的公用类。

1.Nuget 引入:
Microsoft.Extensions.Configuration

Microsoft.Extensions.Configuration.Json

Microsoft.Extensions.Configuration.Binder.

using Microsoft.Extensions.Configuration;

namespace TanYongJun.Common
{
/// <summary>
/// appsettings.json操作类
/// </summary>
public class AppSettingsHelper
{
private static IConfiguration? _config; public AppSettingsHelper(IConfiguration configuration)
{
_config = configuration;
} /// <summary>
/// 读取指定节点的字符串
/// </summary>
/// <param name="sessions"></param>
/// <returns></returns>
public static string ReadAppSettings(params string[] sessions)
{
try
{
if (sessions.Any())
{
return _config[string.Join(":", sessions)];
}
}
catch
{
return "";
}
return "";
} /// <summary>
/// 读取实体信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="session"></param>
/// <returns></returns>
public static List<T> ReadAppSettings<T>(params string[] session)
{
List<T> list = new List<T>();
_config.Bind(string.Join(":", session), list);
return list;
} }
}

  

2.注入 

3.使用:

最新文章

  1. 通过adb方式给安卓手机截图的cmd批处理文件
  2. ZKWeb网页框架1.2正式发布
  3. Genymotion自动化启动
  4. HTML+CSS页面滚动效果处理
  5. SQL Server 错误:15023(创建对于用户失败)
  6. 使用 CodeIgniter 框架快速开发 PHP 应用(一)
  7. shell sed
  8. Linux Redis集群搭建与集群客户端实现(Python)
  9. 设置QT应用程序图标方法(Windows下)
  10. [BZOJ1977]严格次小生成树
  11. Django 载入静态文件地址
  12. 点击事件click和onclick的区别
  13. Windows 使用 Gogs 搭建 Git 服务器
  14. sublime格式化js、css、html的通用插件-html js css pretty
  15. nginx_lua_waf 部署、测试记录
  16. LightOJ 1027 A Dangerous Maze(期望)
  17. Generator [ˈdʒenəreɪtə(r)] 函数结构
  18. Hibernate的批量处理和分页技术、投影技术
  19. iOS 友盟统计怎么用
  20. OpenCL™ 2.0 – Pipes

热门文章

  1. History模式的配置细节
  2. 【转载】EXCEL VBA 20个有用的ExcelVBA代码
  3. [论文总结] kmeans聚类和WGCNA
  4. Hadoop详解(04)-Hdfs
  5. dotnet 代码优化 聊聊逻辑圈复杂度
  6. Springboot+Dplayer+RabbitMQ实现视频弹幕延时入库
  7. 字符输入流读取字符数据-writer类
  8. Monkey 命令
  9. Redis-05持久化
  10. day11-JSON处理和HttpMessageConverter&lt;T&gt;