EI-Image-Viewer-Api/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs

937 lines
33 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using AutoMapper;
using IRaCIS.Core.Domain.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using AutoMapper.QueryableExtensions;
using EFCore.BulkExtensions;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.Data.SqlClient;
using Newtonsoft.Json;
using IRaCIS.Core.Infra.EFCore.Dto;
namespace IRaCIS.Core.Infra.EFCore
{
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : Entity, new()
{
public IMapper _mapper { get; set; }
public IRaCISDBContext _dbContext { get; set; }
public DbSet<TEntity> _dbSet => _dbContext.Set<TEntity>();
public IUserInfo _userInfo { get; set; }
public Repository(IRaCISDBContext dbContext, IMapper mapper, IUserInfo userInfo)
{
_dbContext = dbContext;
_mapper = mapper;
_userInfo = userInfo;
}
#region 异步部分
public async Task<TEntity> InsertOrUpdateAsync<TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<TEntity>[] verify)
{
var entity = _mapper.Map<TEntity>(from);
if (entity.Id == Guid.Empty)
{
return await InsertFromDTOAsync(from, autoSave, verify);
}
else
{
return await UpdateFromDTOAsync(from, autoSave, false, verify);
}
}
private async Task EntityVerifyAsync(bool isAdd, EntityVerifyExp<TEntity>[] verify, Guid? entitydId = null)
{
if (isAdd)
{
foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify))
{
if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
{
throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
}
}
}
else
{
foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify))
{
if (verifyItem.verifyType == VerifyEnum.OnlyUpdate)
{
if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
{
throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
}
}
else if (verifyItem.verifyType == VerifyEnum.Both)
{
if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entitydId)).ConfigureAwait(false))
{
throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
}
}
}
}
}
public async Task<TEntity> InsertFromDTOAsync<TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<TEntity>[] verify)
{
List<DataInspection> datas = new List<DataInspection>();
var entity = _mapper.Map<TEntity>(from);
await EntityVerifyAsync(true, verify);
await _dbSet.AddAsync(entity).ConfigureAwait(false);
await SaveChangesAsync(autoSave);
var createtime = DateTime.Now.AddSeconds(1);
// 受试者
if (typeof(TEntity) == typeof(Subject))
{
Subject data = entity as Subject;
datas.Add(new DataInspection()
{
TrialId = data.TrialId,
SiteId = data.SiteId,
SubjectId = data.Id,
SubjectCode = data.Code,
IsSign = false,
CreateTime = createtime,
Identification = "Init|Subject|Status|Subject",
JsonDetail = JsonConvert.SerializeObject(new
{
Status = "新增",
})
});
}
await AddListInspectionRecordAsync(datas);
return entity;
}
#region 稽查
/// <summary>
/// 添加稽查记录
/// </summary>
/// <param name="datas"></param>
/// <returns></returns>
public async Task AddListInspectionRecordAsync(List<DataInspection> datas)
{
//var trialIds= datas.Select(x=>x.TrialId).Distinct().ToList();
//var subjectVisitIds= datas.Select(x=>x.SubjectVisitId).Distinct().ToList();
//var subjectIds = datas.Select(x => x.SubjectId).Distinct().ToList();
//var siteIds = datas.Select(x => x.SiteId).Distinct().ToList();
//var childrenTypes= datas.Select(x => x.ChildrenType).Distinct().ToList();
//var objectTypes = datas.Select(x => x.ObjectType).Distinct().ToList();
foreach (var add in datas)
{
await SetInspectionNameValue(add);
if (add.ParentId == null)
{
add.ParentId = (await _dbContext.DataInspection.AsQueryable().Where(x => x.TrialId == add.TrialId && x.SubjectVisitId == add.SubjectVisitId && x.SubjectId == add.SubjectId && x.SiteId == add.SiteId && x.ChildrenType == add.ChildrenType && x.ObjectType == add.ObjectType && x.VisitStageId == add.VisitStageId && x.GeneralId == add.GeneralId).OrderByDescending(x => x.CreateTime).FirstOrDefaultAsync())?.Id;
}
add.CreateUserId = _userInfo.Id;
add.IP = _userInfo.IP;
var JsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>(add.JsonDetail);
foreach (var item in JsonData.Keys)
{
if (JsonData[item] == null)
{
continue;
}
if (JsonData[item].ToString().ToLower() == "true".ToLower())
{
JsonData[item] = "是";
}
else if (JsonData[item].ToString().ToLower() == "false".ToLower())
{
JsonData[item] = "否";
}
}
if (add.CreateTime == default(DateTime))
{
add.CreateTime = DateTime.Now;
}
add.JsonDetail = JsonConvert.SerializeObject(JsonData);
await SetDataInspectionDateType(add);
}
await _dbContext.DataInspection.AddRangeAsync(datas);
}
/// <summary>
/// IsNullOrEmpty
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private bool IsNullOrEmpty(object value)
{
if (value == null || value.ToString() == string.Empty)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 格式化日期和时间
/// </summary>
/// <param name="Data"></param>
/// <returns></returns>
public async Task<DataInspection> SetDataInspectionDateType(DataInspection Data)
{
var list = await (from parent in _dbContext.FrontAuditConfig.AsQueryable().Where(x => x.Identification == Data.Identification)
join child in _dbContext.FrontAuditConfig.AsQueryable().Where(x => x.DateType != null && x.DateType != string.Empty) on parent.Id equals child.ParentId
select new DateDto()
{
Code= child.Code,
DateType= child.DateType,
}).ToListAsync();
var JsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>(Data.JsonDetail);
foreach (var item in JsonData.Keys)
{
var datefirst = list.FirstOrDefault(x => x.Code.ToLower() == item.ToLower());
if (datefirst != null&& !IsNullOrEmpty(JsonData[item]))
{
try
{
if (datefirst.DateType == "Date")
{
JsonData[item] = DateTime.Parse(JsonData[item].ToString()).ToString("yyyy-MM-dd");
}
if (datefirst.DateType == "DateTime")
{
JsonData[item] = DateTime.Parse(JsonData[item].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
}
}
catch (Exception)
{
continue;
}
}
}
Data.JsonDetail = JsonConvert.SerializeObject(JsonData);
return Data;
}
/// <summary>
/// 设置项目以及名称
/// </summary>
/// <param name="Data"></param>
/// <returns></returns>
public async Task SetInspectionNameValue(DataInspection Data)
{
#region 项目名称
var trialdata = await _dbContext.Trial.Select(x=>new { x.Id, x.ResearchProgramNo, x.ExperimentName, }).FirstOrDefaultAsync(x => x.Id == Data.TrialId);
Data.ResearchProgramNo = trialdata?.ResearchProgramNo;
if (IsNullOrEmpty(Data.TrialName))
{
Data.TrialName = trialdata?.ExperimentName;
}
#endregion
#region 测试中心名称
Data.SiteCode = (await _dbContext.TrialSite.IgnoreQueryFilters().FirstOrDefaultAsync(x => x.TrialId == Data.TrialId && x.SiteId == Data.SiteId))?.TrialSiteCode;
if (IsNullOrEmpty(Data.SiteName)&& Data.SiteId!=null)
{
var sitedata = await _dbContext.Site.Where(x => x.Id == Data.SiteId).Select(x=>new { x.SiteName}).FirstOrDefaultAsync();
Data.SiteName = sitedata?.SiteName;
}
#endregion
#region 受试者
if (IsNullOrEmpty(Data.SubjectCode) && Data.SubjectId != null)
{
Data.SubjectCode = (await _dbContext.Subject.Where(x => x.Id == Data.SubjectId).Select(x=>new {x.Code }).FirstOrDefaultAsync())?.Code;
}
#endregion
#region 访视
if (IsNullOrEmpty(Data.SubjectVisitName))
{
Data.SubjectVisitName = (await _dbContext.SubjectVisit.Where(x => x.Id == Data.SubjectVisitId).Select(x=>new { x.VisitName}).FirstOrDefaultAsync())?.VisitName;
}
#endregion
#region 创建者
if (IsNullOrEmpty(Data.CreateUserName))
{
Data.CreateUserName = _userInfo.RealName;
}
if (IsNullOrEmpty(Data.RoleName))
{
Data.RoleName = _userInfo.UserTypeShortName;
}
//if (IsNullOrEmpty(Data.CreateUserName) || IsNullOrEmpty(Data.RoleName))
//{
// var userdata = await _dbContext.Users.AsQueryable().Where(x => x.Id == Data.CreateUserId).GroupJoin(_dbContext.UserType.AsQueryable(), a => a.UserTypeId, b => b.Id, (a, b) => new
// {
// UserName = a.FirstName + a.LastName,
// Role = b
// }).SelectMany(a => a.Role, (m, n) => new
// {
// UserName = m.UserName,
// RoleName = n.UserTypeShortName
// }).FirstOrDefaultAsync();
// if (userdata != null)
// {
// if (IsNullOrEmpty(Data.CreateUserName))
// {
// Data.CreateUserName = userdata?.UserName;
// }
// if (IsNullOrEmpty(Data.RoleName))
// {
// Data.RoleName = userdata?.RoleName;
// }
// }
//}
#endregion
#region 取操作类型
try
{
var from = await _dbContext.FrontAuditConfig.FirstOrDefaultAsync(x => x.Identification == Data.Identification);
Data.ObjectType = from.ObjectTypeId;
Data.OptType = from.OptTypeId;
Data.ChildrenType = from.ChildrenTypeId;
Data.ModuleType = from.ModuleTypeId;
}
catch (Exception)
{
throw new BusinessValidationFailedException("操作标识异常");
}
#endregion
}
#endregion
/// <summary>
/// 用前端传递的视图模型字段,更新,同时返回数据库该条记录的原始信息,方便对比某些字段是否更改,进行相应的逻辑操作
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="from"></param>
/// <param name="autoSave"></param>
/// <param name="ignoreDtoNullProperty"></param>
/// <param name="verify"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public async Task<TEntity> UpdateFromDTOAsync<TFrom>(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp<TEntity>[] verify)
{
var entity = _mapper.Map<TEntity>(from);
await EntityVerifyAsync(false, verify, entity.Id);
var dbEntity = await _dbSet.IgnoreQueryFilters().FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false);
if (dbEntity == null)
{
throw new BusinessValidationFailedException(
" Update object not exist in db,Please check if the parameter Id is passed incorrectly");
}
var dbBeforEntity = dbEntity.Clone();
_mapper.Map(from, dbEntity);
//DTO null 属性不更新 防止意外操作,导致保存数据错误,或者 add 和update 用一个模型更新的时候只传递了部分字段导致不想更新的字段因为没传递值用null覆盖了
// Guid属性 为null 时 映射到 Guid 时 默认会变成 Guid.Empty
if (ignoreDtoNullProperty)
{
var dbEntityProp = typeof(TEntity).GetProperties();
foreach (var propertyInfo in from.GetType().GetProperties())
{
if (propertyInfo.GetValue(from) == null && dbEntityProp.Any(t => t.Name == propertyInfo.Name))
{
_dbContext.Entry(dbEntity).Property(propertyInfo.Name).IsModified = false;
}
}
}
await SaveChangesAsync(autoSave);
return dbBeforEntity;
}
private async Task<bool> SaveChangesAsync(bool autoSave)
{
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
}
/// <summary>
/// 通过主键id 和表达式树 更新部分字段 例如 Guid.Parse("8a90c96e-0776-4f7b-82a6-18933d339584"),u => new Dictionary() { ParentId = null, Code = "test" } 默认会去处理更新更新人 更新时间
/// </summary>
/// <param name="id"></param>
/// <param name="updateFactory"></param>
/// <param name="autoSave"></param>
/// <param name="verify"></param>
/// <returns></returns>
public async Task UpdatePartialFields(Guid id, Expression<Func<TEntity, TEntity>> updateFactory, bool autoSave = false, params EntityVerifyExp<TEntity>[] verify)
{
await SetPartialFieldUpdateAsync(id, updateFactory, verify);
await SaveChangesAsync(autoSave);
}
public async Task<bool> UpdatePartialFieldsNow(Guid id, Expression<Func<TEntity, TEntity>> updateFactory,
params EntityVerifyExp<TEntity>[] verify)
{
await SetPartialFieldUpdateAsync(id, updateFactory, verify);
return await SaveChangesAsync(true);
}
/// <summary>
/// 部分字段更新,注意 模型标注了 ConcurrencyCheck的属性这样的实体不适合用部分字段更新ef生成的更新sql会自动带上ConcurrencyCheck的属性条件
/// </summary>
/// <param name="id"></param>
/// <param name="updateFactory"></param>
/// <param name="verify"></param>
/// <returns></returns>
private async Task SetPartialFieldUpdateAsync(Guid id, Expression<Func<TEntity, TEntity>> updateFactory, params EntityVerifyExp<TEntity>[] verify)
{
await EntityVerifyAsync(false, verify, id);
var entity = new TEntity() { Id = id };
var entityEntry = _dbContext.Entry(entity);
entityEntry.State = EntityState.Detached;
List<PropertyInfo> list = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name)
.Select(propName => typeof(TEntity).GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)).ToList();
Func<TEntity, TEntity> func = updateFactory.Compile();
TEntity applyObj = func(entity);
foreach (PropertyInfo prop in list)
{
object value = prop.GetValue((object)applyObj);
prop.SetValue((object)entity, value);
_dbContext.Entry(entity).Property(prop.Name).IsModified = true;
}
#region Test
//updateFactory.Compile()(entity);
//List<string> propNameList = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name).ToList();
//foreach (string propName in propNameList)
//{
// _dbContext.Entry(entity).Property(propName).IsModified = true;
//}
#endregion
}
/// <summary>
/// 部分字段更新 (只更新传递的字段名 new[] {nameof(User.Name), nameof(User.Age))
/// new Dictionary() { ParentId = null, Code = "test"Id=Guid.Parse("8a90c96e-0776-4f7b-82a6-18933d339584")},new[] {nameof(Dictionary.Name), nameof(Dictionary.Age))
/// </summary>
/// <param name="entity"></param>
/// <param name="propertyNames"> 更新的字段数组 </param>
/// <param name="autoSave"></param>
/// <param name="ignoreEntityNullProperty"></param>
/// <param name="verify"></param>
/// <returns></returns>
public async Task<TEntity> UpdatePartialFields(TEntity entity, string[] propertyNames,
bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp<TEntity>[] verify)
{
await EntityVerifyAsync(false, verify, entity.Id);
var entityEntry = _dbContext.Entry(entity);
entityEntry.State = EntityState.Detached;
foreach (var propertyName in propertyNames)
{
_dbContext.Entry(entity).Property(propertyName).IsModified = true;
}
// 忽略空值
IgnoreNullValues(ref entity, ignoreEntityNullProperty);
return entityEntry.Entity;
}
/// <summary>
/// 更新 排除某些字段的更新 排除方式: new[] {nameof(User.Name), nameof(User.Age)
/// </summary>
/// <param name="entity"></param>
/// <param name="propertyNames"></param>
/// <param name="autoSave"></param>
/// <param name="ignoreEntityNullProperty"></param>
/// <param name="verify"></param>
/// <returns></returns>
public async Task<TEntity> UpdateExcludeFields(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp<TEntity>[] verify)
{
await EntityVerifyAsync(false, verify, entity.Id);
var entityEntry = _dbContext.Entry(entity);
entityEntry.State = EntityState.Modified;
foreach (var propertyName in propertyNames)
{
_dbContext.Entry(entity).Property(propertyName).IsModified = false;
}
// 忽略空值
IgnoreNullValues(ref entity, ignoreEntityNullProperty);
return entityEntry.Entity;
}
/// <summary>
/// 忽略空值属性
/// </summary>
/// <param name="entity"></param>
/// <param name="ignoreNullValues"></param>
private void IgnoreNullValues(ref TEntity entity, bool? ignoreNullValues = null)
{
var isIgnore = ignoreNullValues;
if (isIgnore == false) return;
// 获取所有的属性
var properties = _dbSet.EntityType.GetProperties();
if (properties == null) return;
foreach (var propety in properties)
{
var entityProperty = _dbContext.Entry(entity).Property(propety.Name);
var propertyValue = entityProperty?.CurrentValue;
var propertyType = entityProperty?.Metadata?.PropertyInfo?.PropertyType;
// 判断是否是无效的值,比如为 null默认时间以及空 Guid 值
var isInvalid = propertyValue == null
|| (propertyType == typeof(DateTime) && propertyValue?.ToString() == new DateTime().ToString())
|| (propertyType == typeof(DateTimeOffset) && propertyValue?.ToString() == new DateTimeOffset().ToString())
|| (propertyType == typeof(Guid) && propertyValue?.ToString() == Guid.Empty.ToString());
if (isInvalid && entityProperty != null)
{
entityProperty.IsModified = false;
}
}
}
public async Task<bool> SaveChangesAsync(CancellationToken cancellationToken = default)
{
return await _dbContext.SaveChangesAsync(cancellationToken) > 0;
}
public async ValueTask<TEntity> FindAsync(Guid id, CancellationToken cancellationToken = default)
{
return await _dbContext.FindAsync<TEntity>(id);
}
//有可能是联合主键本项目没用到用Guid
public async ValueTask<TEntity> FindAsync(object[] keyValues, CancellationToken cancellationToken)
{
return await _dbContext.FindAsync<TEntity>(keyValues);
}
public async Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> exp = null, bool ignoreQueryFilters = false)
{
var query = _dbSet.AsQueryable();
if (ignoreQueryFilters)
{
query = query.IgnoreQueryFilters();
}
if (exp == null)
return await query.FirstOrDefaultAsync().ConfigureAwait(false);
return await query.FirstOrDefaultAsync(exp).ConfigureAwait(false);
}
public async ValueTask<TEntity> AddAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
await _dbSet.AddAsync(entity).ConfigureAwait(false);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
return entity;
}
public async Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities)
{
await _dbSet.AddRangeAsync(entities).ConfigureAwait(false);
return entities;
}
public async Task<bool> AddRangeAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
await _dbSet.AddRangeAsync(entities).ConfigureAwait(false);
if (autoSave)
{
return await SaveChangesAsync(cancellationToken);
}
else
{
return false;
}
}
public async Task<TResult> MaxAsync<TResult>(Expression<Func<TEntity, TResult>> selector)
{
return await _dbSet.AsNoTracking().MaxAsync(selector);
}
public async Task<bool> AnyAsync(Expression<Func<TEntity, bool>> exp, bool ignoreQueryFilters = false)
{
var query = _dbSet.AsQueryable();
if (ignoreQueryFilters)
{
query = query.IgnoreQueryFilters();
}
return await query.AsNoTracking().AnyAsync(exp);
}
public async Task<int> CountAsync(Expression<Func<TEntity, bool>> whereLambda = null, bool ignoreQueryFilters = false)
{
var query = _dbSet.AsQueryable();
if (ignoreQueryFilters)
{
query = query.IgnoreQueryFilters();
}
return whereLambda == null ? await query.AsNoTracking().CountAsync() : await query.AsNoTracking().CountAsync(whereLambda);
}
public async Task<bool> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
_dbSet.Update(entity);
if (autoSave)
{
return await SaveChangesAsync(cancellationToken);
}
else
{
return false;
}
}
public async Task<bool> DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
_dbSet.Remove(entity);
//var entry = _dbSet.Attach(entity);
//entry.State = EntityState.Deleted;
if (autoSave)
{
return await SaveChangesAsync(cancellationToken);
}
else
{
return false;
}
}
public async Task<bool> BatchDeleteAsync(Expression<Func<TEntity, bool>> deleteFilter)
{
return await _dbSet.IgnoreQueryFilters().Where(deleteFilter).BatchDeleteAsync() > 0;
}
public async Task<bool> BatchUpdateAsync(Expression<Func<TEntity, bool>> where,
Expression<Func<TEntity, TEntity>> updateFactory)
{
var bindings = ((MemberInitExpression)updateFactory.Body).Bindings.ToList();
if (typeof(IAuditUpdate).IsAssignableFrom(typeof(TEntity)))
{
var hasPropNameList = bindings.Select(t => t.Member.Name).ToList();
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
{
bindings.Add(Expression.Bind(typeof(TEntity).GetMember(nameof(IAuditUpdate.UpdateTime))[0], Expression.Constant(DateTime.Now)));
}
if (!hasPropNameList.Contains( nameof(IAuditUpdate.UpdateUserId)))
{
bindings.Add(Expression.Bind(typeof(TEntity).GetMember(nameof(IAuditUpdate.UpdateUserId))[0], Expression.Constant(_userInfo.Id)));
}
}
var member = Expression.MemberInit(Expression.New(typeof(TEntity)), bindings);
var factory = Expression.Lambda<Func<TEntity, TEntity>>(member, Expression.Parameter(typeof(TEntity), "x"));
return await _dbSet.IgnoreQueryFilters().Where(where).BatchUpdateAsync(factory) > 0;
}
#endregion
#region 非异步部分
public TEntity ImageFind(Guid id, Type type)
{
//重传的时候 状态为修改 上传的时候状态为添加 内存中有,就不要重复查询数据库了
var list = _dbContext.ChangeTracker.Entries()
.Where(u => (u.State == EntityState.Added || u.State == EntityState.Modified) && (u.Entity.GetType() == type)).Select(t => t.Entity as TEntity);
var entity = list.FirstOrDefault(t => t.Id == id);
if (entity == null)
{
return _dbSet.FirstOrDefault(t => t.Id == id);
}
else
{
return entity;
}
}
public IQueryable<TEntity> AsQueryable(bool ignoreQueryFilters = false)
{
var query = _dbSet.AsQueryable();
if (ignoreQueryFilters)
{
query = query.IgnoreQueryFilters();
}
return query.AsNoTracking();
}
public IQueryable<TResult> Select<TResult>(Expression<Func<TEntity, TResult>> selector)
{
return _dbSet.AsNoTracking().Select(selector);
}
public IQueryable<TEntity> WhereIf(bool condition, Expression<Func<TEntity, bool>> filter)
{
return condition ? _dbSet.AsNoTracking().Where(filter) : _dbSet.AsNoTracking();
}
public IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> exp = null, bool isTraking = false, bool ignoreQueryFilters = false)
{
IQueryable<TEntity> query = _dbSet;
if (!isTraking)
{
query = query.AsNoTracking();
}
if (ignoreQueryFilters)
{
query = query.IgnoreQueryFilters();
}
if (exp != null)
{
query = query.Where(exp);
}
return query;
}
public EntityEntry Entry(TEntity t)
{
return _dbContext.Entry(t);
}
public EntityEntry<TEntity> Attach(TEntity entity)
{
return _dbSet.Attach(entity);
}
public void Detached(TEntity t)
{
_dbContext.Entry(t).State = EntityState.Detached;
}
// automapper 相关
public IQueryable<TDestination> ProjectTo<TDestination>(IConfigurationProvider configuration, object parameters, params Expression<Func<TDestination, object>>[] membersToExpand)
{
return _dbSet.AsNoTracking().ProjectTo(configuration, parameters, membersToExpand);
}
public IQueryable<TDestination> ProjectTo<TDestination>(IConfigurationProvider configuration, params Expression<Func<TDestination, object>>[] membersToExpand)
{
return _dbSet.AsNoTracking().ProjectTo(configuration, membersToExpand);
}
public IQueryable<TDestination> ProjectTo<TDestination>(IConfigurationProvider configuration, IDictionary<string, object> parameters, params string[] membersToExpand)
{
return _dbSet.AsNoTracking().ProjectTo<TDestination>(configuration, parameters, membersToExpand);
}
/// <summary>
/// 仅仅供字典表插入使用因为efcore 动态映射列的问题
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <param name="from"></param>
/// <param name="verify"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
public async Task<TEntity> InsertDictionaryAsync<TFrom>(TFrom from, params EntityVerifyExp<TEntity>[] verify)
{
var entity = _mapper.Map<TEntity>(from);
foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify))
{
if (await _dbSet.IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
{
throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
}
}
if (typeof(TEntity) == typeof(Dictionary))
{
Type type = typeof(TFrom);
//以下是不要ID这个字段的 比如自增列ID 就不能像上名那样写
var properties = type.GetProperties().Where(t => t.Name != "Id");
string strSqlName = string.Join(",", properties.Select(p => $"[{p.Name}]").ToArray());
string strSqlValue = string.Join(",", properties.Select(P => $"@{P.Name}").ToArray());
string strSql = $"insert into {nameof(Dictionary)} ( " + strSqlName + " ) values (" + strSqlValue + ")";
//para Sql是参数
SqlParameter[] para = properties.Select(p => new SqlParameter($"@{p.Name}", p.GetValue(from, null))).ToArray();
_dbContext.Database.ExecuteSqlRaw(strSql, para);
return entity;
}
else
{
throw new Exception("仅仅供字典表插入使用因为efcore 动态映射列的问题");
//await _dbSet.BulkInsertAsync(new List<TEntity>() { entity });
//return entity;
}
}
#endregion
}
}