修改仓储

This commit is contained in:
2022-06-01 13:59:34 +08:00
parent 5db7715e99
commit 2ca7a63053
7 changed files with 136 additions and 219 deletions
@@ -87,6 +87,20 @@ namespace IRaCIS.Core.Infra.EFCore
EntityEntry Entry(TEntity t);
/// <summary>
///不跟踪 查询单个实体,不会出现NUll
/// </summary>
/// <param name="exp"></param>
/// <param name="ignoreQueryFilters"></param>
/// <returns></returns>
Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> exp = null, bool isTracking = false);
/// <summary>
///跟踪 查询单个实体,会出现NUll
/// </summary>
/// <param name="exp"></param>
/// <param name="ignoreQueryFilters"></param>
/// <returns></returns>
Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> exp = null, bool ignoreQueryFilters = false);
Task<TEntity> FirstOrDefaultNoTrackingAsync(Expression<Func<TEntity, bool>> exp = null, bool ignoreQueryFilters = false);
@@ -97,14 +111,9 @@ namespace IRaCIS.Core.Infra.EFCore
Task<int> CountAsync(Expression<Func<TEntity, bool>> whereLambda = null, bool ignoreQueryFilters = false);
ValueTask<TEntity> AddAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default, bool isSaveAudit = false);
Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities, bool isSaveAudit = false);
//Task<bool> AddRangeAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default);
// 不建议使用,使用跟踪,然后save 部分字段更新,此种方式是更新所有字段
//Task<bool> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
ValueTask<TEntity> AddAsync(TEntity entity, bool autoSave = false);
Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities, bool autoSave = false);
Task<bool> SaveChangesAsync(CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
@@ -13,19 +13,10 @@ using System.Linq.Expressions;
using System.Threading.Tasks;
using EFCore.BulkExtensions;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common.Dto;
using System.Reflection;
namespace IRaCIS.Core.Infra.EFCore
{
public interface IRepository<TEntity> : ICommandRepository<TEntity>, IQueryRepository<TEntity> where TEntity : Entity
{
IRaCISDBContext _dbContext { get; set; }
}
#region
@@ -34,16 +25,12 @@ namespace IRaCIS.Core.Infra.EFCore
{
IQueryable<T> GetQueryable<T>(bool isTraking = false) where T : Entity;
DbSet<T> Set<T>() where T : Entity;
EntityEntry<T> Entry<T>(T t) where T : Entity;
Task<bool> SaveChangesAsync();
IQueryable<T> WhereIf<T>(bool condition, Expression<Func<T, bool>> filter) where T : Entity;
Task<T> InsertOrUpdateAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity;
Task<T> InsertFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity;
Task<T> UpdateFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp<T>[] verify) where T : Entity;
EntityEntry<T> Entry<T>(T t) where T : Entity;
Task<bool> AnyAsync<T>(Expression<Func<T, bool>> filter, bool ignoreQueryFilters = false) where T : Entity;
@@ -54,6 +41,16 @@ namespace IRaCIS.Core.Infra.EFCore
ValueTask<T> FindAsync<T>(Guid id) where T : Entity;
Task<T> InsertOrUpdateAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity;
Task<T> InsertFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity;
Task<T> UpdateFromDTOAsync<T, TFrom>(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp<T>[] verify) where T : Entity;
ValueTask<T> AddAsync<T>(T entity, bool autoSave = false) where T : Entity;
Task UpdateRange<T>(IEnumerable<T> entities, bool autoSave = false) where T : Entity;
@@ -63,9 +60,6 @@ namespace IRaCIS.Core.Infra.EFCore
Task<bool> DeleteAsync<T>(T entity, bool autoSave = false) where T : Entity;
//Task<bool> DeleteManyAsync<T>(IEnumerable<T> entities, bool autoSave = false) where T : Entity;
Task<bool> SaveChangesAsync();
Task<bool> BatchDeleteAsync<T>(Expression<Func<T, bool>> deleteFilter) where T : Entity;
@@ -78,10 +72,8 @@ namespace IRaCIS.Core.Infra.EFCore
public class Repository : IRepository
{
#region
private IRaCISDBContext _dbContext { get; }
public IMapper _mapper { get; set; }
public IUserInfo _userInfo { get; set; }
@@ -99,7 +91,7 @@ namespace IRaCIS.Core.Infra.EFCore
/// <typeparam name="T"></typeparam>
/// <param name="isTraking"></param>
/// <returns></returns>
public IQueryable<T> GetQueryable<T>(bool isTraking = false) where T : Entity
{
IQueryable<T> query = _dbContext.Set<T>();
@@ -115,12 +107,39 @@ namespace IRaCIS.Core.Infra.EFCore
return _dbContext.Set<T>();
}
public EntityEntry<T> Entry<T>(T t) where T : Entity
{
return _dbContext.Entry<T>(t);
}
public IQueryable<T> WhereIf<T>(bool condition, Expression<Func<T, bool>> filter) where T : Entity
{
IQueryable<T> query = _dbContext.Set<T>().AsNoTracking();
return condition ? query.Where(filter) : query;
}
private async Task<bool> SaveChangesAsync(bool autoSave)
{
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
}
public async Task<bool> SaveChangesAsync()
{
return await _dbContext.SaveChangesAsync().ConfigureAwait(false) > 0;
}
#endregion
private async Task EntityVerifyAsync<T>(bool isAdd, EntityVerifyExp<T>[] verify, Guid? entitydId = null) where T : Entity
{
@@ -129,7 +148,7 @@ namespace IRaCIS.Core.Infra.EFCore
{
foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify))
{
if (await _dbContext.Set<T>().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
if (await _dbContext.Set<T>().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
{
throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
}
@@ -141,14 +160,14 @@ namespace IRaCIS.Core.Infra.EFCore
{
if (verifyItem.verifyType == VerifyEnum.OnlyUpdate)
{
if (await _dbContext.Set<T>().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
if (await _dbContext.Set<T>().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false))
{
throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
}
}
else if (verifyItem.verifyType == VerifyEnum.Both)
{
if (await _dbContext.Set<T>().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entitydId)).ConfigureAwait(false))
if (await _dbContext.Set<T>().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entitydId)).ConfigureAwait(false))
{
throw new BusinessValidationFailedException(verifyItem.VerifyMsg);
}
@@ -166,7 +185,6 @@ namespace IRaCIS.Core.Infra.EFCore
await EntityVerifyAsync(true, verify);
entity = await AddAsync(entity, autoSave);
@@ -214,18 +232,6 @@ namespace IRaCIS.Core.Infra.EFCore
}
private async Task<bool> SaveChangesAsync(bool autoSave)
{
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
}
public async Task<T> InsertOrUpdateAsync<T, TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<T>[] verify) where T : Entity
{
@@ -242,10 +248,7 @@ namespace IRaCIS.Core.Infra.EFCore
}
}
public EntityEntry<T> Entry<T>(T t) where T : Entity
{
return _dbContext.Entry<T>(t);
}
public async Task<bool> AnyAsync<T>(Expression<Func<T, bool>> filter, bool ignoreQueryFilters = false) where T : Entity
{
@@ -261,7 +264,7 @@ namespace IRaCIS.Core.Infra.EFCore
}
#region
@@ -368,39 +371,22 @@ namespace IRaCIS.Core.Infra.EFCore
{
await _dbContext.Set<T>().AddRangeAsync(entities).ConfigureAwait(false);
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
return await SaveChangesAsync(autoSave);
}
public async Task UpdateRange<T>(IEnumerable<T> entities, bool autoSave = false) where T : Entity
{
_dbContext.Set<T>().UpdateRange(entities);
if (autoSave)
{
await SaveChangesAsync();
}
await SaveChangesAsync(autoSave);
}
public async Task<bool> UpdateAsync<T>(T entity, bool autoSave = false) where T : Entity
{
_dbContext.Set<T>().Update(entity);
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
return await SaveChangesAsync(autoSave);
}
@@ -408,36 +394,19 @@ namespace IRaCIS.Core.Infra.EFCore
{
_dbContext.Set<T>().Remove(entity);
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
return await SaveChangesAsync(autoSave);
}
public async Task<bool> DeleteManyAsync<T>(IEnumerable<T> entities, bool autoSave = false) where T : Entity
{
_dbContext.Set<T>().RemoveRange(entities);
if (autoSave)
{
return await SaveChangesAsync();
}
else
{
return false;
}
return await SaveChangesAsync(autoSave);
}
public async Task<bool> SaveChangesAsync()
{
return await _dbContext.SaveChangesAsync().ConfigureAwait(false) > 0;
}
#endregion
+43 -100
View File
@@ -14,13 +14,15 @@ 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 Newtonsoft.Json.Linq;
using IRaCIS.Core.Infra.EFCore.Common.Dto;
namespace IRaCIS.Core.Infra.EFCore
{
public interface IRepository<TEntity> : ICommandRepository<TEntity>, IQueryRepository<TEntity> where TEntity : Entity
{
IRaCISDBContext _dbContext { get; set; }
}
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : Entity, new()
{
@@ -42,29 +44,23 @@ namespace IRaCIS.Core.Infra.EFCore
#region EF
public async Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities, bool isSaveAudit = false)
public async Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities, bool autoSave = false)
{
foreach (var addEntity in entities)
{
await AddAsync(addEntity, isSaveAudit);
}
await _dbSet.AddRangeAsync(entities).ConfigureAwait(false);
await SaveChangesAsync(autoSave);
return entities;
}
/// <summary>EF跟踪方式 添加</summary>
public async ValueTask<TEntity> AddAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default, bool isSaveAudit = false)
public async ValueTask<TEntity> AddAsync(TEntity entity, bool autoSave = false)
{
await _dbSet.AddAsync(entity).ConfigureAwait(false);
// 添加稽查
//await AddInspectionAsync(entity, isSaveAudit);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
await SaveChangesAsync(autoSave);
return entity;
}
@@ -73,10 +69,10 @@ namespace IRaCIS.Core.Infra.EFCore
public async Task<TEntity> InsertFromDTOAsync<TFrom>(TFrom from, bool autoSave = false, params EntityVerifyExp<TEntity>[] verify)
{
var entity = _mapper.Map<TEntity>(from);
await EntityVerifyAsync(true, verify);
var entity = _mapper.Map<TEntity>(from);
entity = await AddAsync(entity, autoSave);
@@ -338,11 +334,7 @@ namespace IRaCIS.Core.Infra.EFCore
var query = ignoreQueryFilter ? _dbSet.AsNoTracking().IgnoreQueryFilters() : _dbSet.AsNoTracking();
var waitDeleteList = await query.Where(deleteFilter).ToListAsync();
foreach (var deleteItem in waitDeleteList)
{
await DeleteAsync(deleteItem, false);
}
_dbSet.RemoveRange(waitDeleteList);
await SaveChangesAsync(autoSave);
return waitDeleteList;
@@ -352,11 +344,11 @@ namespace IRaCIS.Core.Infra.EFCore
public async Task<List<TEntity>> SoftDeleteFromQueryAsync(Expression<Func<TEntity, bool>> deleteFilter, bool autoSave = false, bool ignoreQueryFilter = false)
{
var query = ignoreQueryFilter ? _dbSet.IgnoreQueryFilters() : _dbSet;
var waitDeleteList = await query.Where(deleteFilter).ToListAsync();
var waitDeleteList = await query.Where(deleteFilter).ToListAsync();
foreach (var deleteItem in waitDeleteList)
{
if(deleteItem is ISoftDelete softDeleteItem)
if (deleteItem is ISoftDelete softDeleteItem)
{
softDeleteItem.IsDeleted = true;
}
@@ -618,6 +610,30 @@ namespace IRaCIS.Core.Infra.EFCore
return await _dbContext.FindAsync<TEntity>(keyValues);
}
public async Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> exp = null, bool isTracking = false)
{
var query = _dbSet.AsQueryable();
if (!isTracking)
{
query = query.AsNoTracking();
}
var entity = await query.FirstOrDefaultAsync();
if (entity is null)
{
throw new QueryBusinessObjectNotExistException($"The query object {typeof(TEntity).Name} does not exist in database, Please check the query parameters");
}
else
{
return entity;
}
}
public async Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> exp = null, bool ignoreQueryFilters = false)
{
@@ -764,79 +780,6 @@ namespace IRaCIS.Core.Infra.EFCore
}
#endregion
#region
/// <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;
}
}
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;
}
}
#endregion
}