基于NET Core EF创建基类(方便操作)
一、安装Get包
1、AutoMapper 2、EmitMapper
二、Service类

using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Linq; using Modelsql.DTO; using Yes.Manage.IService; using EmitMapper; using AutoMapper; using Microsoft.EntityFrameworkCore; namespace Yes.Manage.Service { public abstract class BaseService<T, TEntityDto, TKey, TGetAllInput, TCreateInput, TUpdateInput> : IBaseService<T, TEntityDto, TKey, TGetAllInput, TCreateInput, TUpdateInput> where T : class { private LanXiFangYiContext dbContext; public virtual LanXiFangYiContext DbContext { get { if (dbContext == null) { dbContext = GetContext("mycontext"); } return dbContext; } } protected LanXiFangYiContext GetContext(string key) { try { object context = CallContext.GetData(key); if (context == null) { context = new LanXiFangYiContext(); CallContext.SetData(key, context); } return context as LanXiFangYiContext; } catch (Exception ex) { return null; } } public virtual bool Add(T model) { DbContext.Add<T>(model); return DbContext.SaveChanges() > 0 ? true : false; } public virtual IList<T> GetList(Expression<Func<T, bool>> whereLambda) { return DbContext.Set<T>().Where(whereLambda).ToList(); } public virtual int GetListCount(Expression<Func<T, bool>> whereLambda) { return DbContext.Set<T>().Count(whereLambda); } public virtual IList<T> GetListOrderBy(Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderLambda) { return DbContext.Set<T>().Where(whereLambda).OrderBy(orderLambda).ToList(); } public virtual IList<T> GetListOrderByDescending(Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderLambda) { return DbContext.Set<T>().Where(whereLambda).OrderByDescending(orderLambda).ToList(); } public virtual IList<T> GetListOrderByDescending(Expression<Func<T, bool>> whereLambda, IList<Expression<Func<T, object>>> orderLambdaList) { IQueryable<T> queryable = DbContext.Set<T>().Where(whereLambda); IOrderedQueryable<T> orderQuer; if (orderLambdaList.Count > 0) { orderQuer = queryable.OrderByDescending(orderLambdaList[0]); for (int i = 1; i < orderLambdaList.Count; i++) { orderQuer = orderQuer.ThenByDescending(orderLambdaList[i]); } return orderQuer.AsNoTracking().ToList(); } return queryable.AsNoTracking().ToList(); } public virtual IList<T> GetPagedListOrderBy(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderBy) { return DbContext.Set<T>().Where(whereLambda).OrderBy(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToList(); } public virtual IList<T> GetPagedListOrderByDescending(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderBy) { return DbContext.Set<T>().Where(whereLambda).OrderByDescending(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToList(); } public virtual IList<T> GetSkipPagedListOrderByDescending(int skipCount, int maxResultCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderBy) { return DbContext.Set<T>().Where(whereLambda).OrderByDescending(orderBy).Skip((skipCount > 0 ? (skipCount - 1) : 0) * maxResultCount).Take(maxResultCount).AsNoTracking().ToList(); } public IList<T> GetPagedListOrderByDescending(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, IList<Expression<Func<T, object>>> orderByList) { IQueryable<T> queryable = DbContext.Set<T>().Where(whereLambda); IOrderedQueryable<T> orderQuer; if (orderByList.Count > 0) { orderQuer = queryable.OrderByDescending(orderByList[0]); for (int i = 1; i < orderByList.Count; i++) { orderQuer = orderQuer.ThenByDescending(orderByList[i]); } return orderQuer.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToList(); } return queryable.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsNoTracking().ToList(); } public virtual T GetSingle(Expression<Func<T, bool>> whereLambda) { return DbContext.Set<T>().SingleOrDefault(whereLambda); } public virtual bool Remove(T model) { try { DbContext.Set<T>().Remove(model); return DbContext.SaveChanges() > 0 ? true : false; } catch { return false; } } //public abstract Task<bool> Remove(TKey key); public virtual bool Update(T model) { DbContext.Set<T>().Update(model); return DbContext.SaveChanges() > 0 ? true : false; } public T GetFirst(Expression<Func<T, bool>> whereLambda) { return DbContext.Set<T>().FirstOrDefault(whereLambda); } public virtual TDto MapToEntityDto<TDto>(T entity) { if (entity == null) return default; ObjectsMapper<T, TDto> mapper = ObjectMapperManager.DefaultInstance.GetMapper<T, TDto>(); return mapper.Map(entity); } public virtual TEntityDto MapToEntityDto(T entity) { if (entity == null) return default; ObjectsMapper<T, TEntityDto> mapper = ObjectMapperManager.DefaultInstance.GetMapper<T, TEntityDto>(); return mapper.Map(entity); } public virtual T MapToEntity(TCreateInput createInput) { if (createInput == null) return default; ObjectsMapper<TCreateInput, T> mapper = ObjectMapperManager.DefaultInstance.GetMapper<TCreateInput, T>(); return mapper.Map(createInput); } public virtual T MapTUpdateToEntity(TUpdateInput updateInput, T entity) { if (updateInput == null) return default; ObjectsMapper<TUpdateInput, T> mapper = ObjectMapperManager.DefaultInstance.GetMapper<TUpdateInput, T>(); return mapper.Map(updateInput, entity); //MapperConfiguration mapperConfiguration = new MapperConfiguration(n => n.CreateMap<TUpdateInput, T>().ReverseMap()); //Mapper mapper = new Mapper(mapperConfiguration); //return mapper.Map<T>(updateInput); } public T MapTo(object source) { if (source == null) return default; MapperConfiguration mapperConfiguration = new MapperConfiguration(n => n.CreateMap<object, T>().ReverseMap()); Mapper mapper = new Mapper(mapperConfiguration); return mapper.Map<T>(source.GetType()); //ObjectsMapper<object, T> mapper = ObjectMapperManager.DefaultInstance.GetMapper<object, T>(); //return mapper.Map(source); } public virtual TDto GetDto<TDto>(Expression<Func<T, bool>> whereLambda) { return MapToEntityDto<TDto>(GetSingle(whereLambda)); } public virtual TEntityDto GetDto(Expression<Func<T, bool>> whereLambda) { return MapToEntityDto(GetSingle(whereLambda)); } public T GetAsync(TKey key) { return DbContext.Set<T>().FirstOrDefault(CreateEqualityExpressionForId(key)); } protected virtual Expression<Func<T, bool>> CreateEqualityExpressionForId(TKey id) { var lambdaParam = Expression.Parameter(typeof(T)); var leftExpression = Expression.PropertyOrField(lambdaParam, "Id"); var idValue = Convert.ChangeType(id, typeof(TKey)); Expression<Func<object>> closure = () => idValue; var rightExpression = Expression.Convert(closure.Body, leftExpression.Type); var lambdaBody = Expression.Equal(leftExpression, rightExpression); return Expression.Lambda<Func<T, bool>>(lambdaBody, lambdaParam); } } }
三、IService类

using System; using System.Collections.Generic; using System.Linq.Expressions; namespace Yes.Manage.IService { public interface IBaseService<T, TEntityDto, TKey, TGetAllInput, TCreateInput, TUpdateInput> where T : class { T GetSingle(Expression<Func<T, bool>> whereLambda); T GetFirst(Expression<Func<T, bool>> whereLambda); bool Add(T model); bool Update(T model); bool Remove(T model); // Task<bool> Remove(TKey key); #region 获取列表 list IList<T> GetList(Expression<Func<T, bool>> whereLambda); IList<T> GetListOrderBy(Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderLambda); IList<T> GetListOrderByDescending(Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderLambda); IList<T> GetListOrderByDescending(Expression<Func<T, bool>> whereLambda, IList<Expression<Func<T, object>>> orderByList); IList<T> GetPagedListOrderBy(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderBy); IList<T> GetPagedListOrderByDescending(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderBy); IList<T> GetSkipPagedListOrderByDescending(int skipCount, int maxResultCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, object>> orderBy); IList<T> GetPagedListOrderByDescending(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, IList<Expression<Func<T, object>>> orderByList); int GetListCount(Expression<Func<T, bool>> whereLambda); #endregion #region 获取列表IQueryable #endregion TDto MapToEntityDto<TDto>(T entity); TEntityDto MapToEntityDto(T entity); T MapToEntity(TCreateInput createInput); T MapTUpdateToEntity(TUpdateInput updateInput, T entity); TDto GetDto<TDto>(Expression<Func<T, bool>> whereLambda); TEntityDto GetDto(Expression<Func<T, bool>> whereLambda); T GetAsync(TKey key); } }
四、CallContext类(CallContext线程数据缓存-调用上下文,)
- SetData: 存储给定的对象并将其与指定名称关联。
- GetData: 从CallContext中检索具有指定名称的对象
- 优点
- 可以利用CallContext 实现单例,默认情况下,CallContext 的数据不跨线程传播。
-
1、在处理多组件共用Context时非常有用,比如常见的EF 可以将实例的DBEntity存储在其中,可以一次访问只实例化一次,便于管理且不用多次实例访问对象

using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Modelsql.DTO { public class CallContext { static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>(); public static void SetData(string name, object data) { lock (state) { if (!state.TryGetValue(name, out AsyncLocal<object> mydata)) state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data; } } public static object GetData(string name) => state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null; } }
五、YesAuditlog数据表对应的操作类

public class ActionLogService : BaseService<YesAuditlog, ActionLogDto, int, PagedActionLogResultRequestDto, YesAuditlog, YesAuditlog>, IActionLogService { private readonly IYesUserSession userSession; public ActionLogService() { } public ActionLogService(IYesUserSession userSession) { this.userSession = userSession; } public YesAuditlog GetActionLogById(int id) { return base.GetFirst(o => o.Id == id); } public override bool Add(YesAuditlog log) { log.UserId = userSession.GetCurrentUserId(); return base.Add(log); } /// <summary> /// 重写Map方法 /// </summary> /// <param name="auditLog"></param> /// <returns></returns> public override ActionLogDto MapToEntityDto(YesAuditlog auditLog) { if (auditLog == null) return null; var actionLogDto = base.MapToEntityDto(auditLog); actionLogDto.UserName = DbContext.Set<YesUser>().FirstOrDefault(o => o.Id == (long)auditLog.UserId)?.UserName; if (auditLog.UserId.HasValue && auditLog.UserId > 0) { var roleIds = DbContext.Set<YesUserrole>().Where(o => o.UserId == auditLog.UserId).Select(o => o.RoleId); actionLogDto.RoleName = string.Join(',', DbContext.Set<YesRole>().Where(o => roleIds.Contains(o.Id)).Select(o => o.Name).ToArray()); } return actionLogDto; } }