using AutoMapper; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; namespace IRaCIS.Core.Infra.EFCore { public interface IRepository : ICommandRepository, IQueryRepository where TEntity : Entity { } #region 泛型通用版本 public interface IRepository { IQueryable GetQueryable(bool isTraking = false) where T : Entity; DbSet Set() where T : Entity; IQueryable WhereIf(bool condition, Expression> filter) where T : Entity; Task InsertOrUpdateAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) where T : Entity; EntityEntry Entry(T t) where T : Entity; //Task InsertOrUpdateAsync(this DbSet dbset, TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) where T : Entity; Task AnyAsync(Expression> filter, bool ignoreQueryFilters = false) where T : Entity; Task FirstOrDefaultAsync(Expression> exp = null, bool ignoreQueryFilters = false) where T : Entity; Task CountAsync(Expression> exp = null, bool ignoreQueryFilters = false) where T : Entity; IQueryable Where(Expression> exp = null, bool isTraking = false, bool ignoreQueryFilters = false) where T : Entity; ValueTask FindAsync(Guid id) where T : Entity; ValueTask AddAsync(T entity, bool autoSave = false) where T : Entity; Task UpdateRange(IEnumerable entities, bool autoSave = false) where T : Entity; Task AddRangeAsync(IEnumerable entities, bool autoSave = false) where T : Entity; Task UpdateAsync(T entity, bool autoSave = false) where T : Entity; Task DeleteAsync(T entity, bool autoSave = false) where T : Entity; Task DeleteManyAsync(IEnumerable entities, bool autoSave = false) where T : Entity; Task SaveChangesAsync(); Task DeleteFromQueryAsync(Expression> deleteFilter) where T : Entity; Task UpdateFromQueryAsync(Expression> where, Expression> updateFactory) where T : Entity; } public class Repository : IRepository { private IRaCISDBContext _dbContext { get; } public IMapper _mapper { get; set; } public Repository(IRaCISDBContext dbContext, IMapper mapper) { _dbContext = dbContext; _mapper = mapper; } /// /// 设置是使用哪个仓储 默认不跟踪 /// /// /// /// public IQueryable GetQueryable(bool isTraking = false) where T : Entity { IQueryable query = _dbContext.Set(); if (!isTraking) { query = query.AsNoTracking(); } return query; } public DbSet Set() where T : Entity { return _dbContext.Set(); } public IQueryable WhereIf(bool condition, Expression> filter) where T : Entity { IQueryable query = _dbContext.Set().AsNoTracking(); return condition ? query.Where(filter) : query; } public async Task InsertOrUpdateAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) where T : Entity { var entity = _mapper.Map(from); if (entity.Id == Guid.Empty) { // verifyExp //await verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify).ToList().ForeachAsync(async verifyItem => //{ // if (await _dbContext.Set().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) // { // throw new BusinessValidationFailedException(verifyItem.VerifyMsg); // } //}); foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify)) { if (await _dbContext.Set().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) { throw new BusinessValidationFailedException(verifyItem.VerifyMsg); } } await _dbContext.Set().AddAsync(entity).ConfigureAwait(false); if (autoSave) { await SaveChangesAsync(); } return entity; } else { // verifyExp //await verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify).ToList().ForeachAsync(async verifyItem => // { // if (verifyItem.verifyType == VerifyEnum.OnlyUpdate) // { // if (await _dbContext.Set().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) // { // throw new BusinessValidationFailedException(verifyItem.VerifyMsg); // } // } // else if (verifyItem.verifyType == VerifyEnum.Both) // { // if (await _dbContext.Set().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entity.Id)).ConfigureAwait(false)) // { // throw new BusinessValidationFailedException(verifyItem.VerifyMsg); // } // } // }); foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify)) { if (verifyItem.verifyType == VerifyEnum.OnlyUpdate) { if (await _dbContext.Set().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) { throw new BusinessValidationFailedException(verifyItem.VerifyMsg); } } else if (verifyItem.verifyType == VerifyEnum.Both) { if (await _dbContext.Set().IgnoreQueryFilters().AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entity.Id)).ConfigureAwait(false)) { throw new BusinessValidationFailedException(verifyItem.VerifyMsg); } } } var dbEntity = await FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false); var dbBeforEntity = dbEntity.Clone(); _mapper.Map(from, dbEntity); if (autoSave) { await SaveChangesAsync(); } return dbBeforEntity; } } public EntityEntry Entry(T t) where T : Entity { return _dbContext.Entry(t); } public async Task AnyAsync(Expression> filter, bool ignoreQueryFilters = false) where T : Entity { var query = _dbContext.Set().AsQueryable(); if (ignoreQueryFilters) { query = query.IgnoreQueryFilters(); } return await query.AsNoTracking().AnyAsync(filter).ConfigureAwait(false); } #region 基本查询 异步 /// /// 跟踪查询某个实体 --异步 默认是跟踪查询 /// /// /// /// /// public async Task CountAsync(Expression> exp = null, bool ignoreQueryFilters = false) where T : Entity { var query = _dbContext.Set().AsQueryable(); if (ignoreQueryFilters) { query = query.IgnoreQueryFilters(); } if (exp != null) { query = query.Where(exp); } return await query.CountAsync().ConfigureAwait(false); } public async Task FirstOrDefaultAsync(Expression> exp = null, bool ignoreQueryFilters = false) where T : Entity { var query = _dbContext.Set().AsQueryable(); if (ignoreQueryFilters) { query = query.IgnoreQueryFilters(); } if (exp != null) { query = query.Where(exp); } return await query.FirstOrDefaultAsync().ConfigureAwait(false); } /// /// 过滤 默认不跟踪 /// /// /// /// /// public IQueryable Where(Expression> exp = null, bool isTraking = false, bool ignoreQueryFilters = false) where T : Entity { IQueryable query = _dbContext.Set(); if (ignoreQueryFilters) { query = query.IgnoreQueryFilters(); } if (!isTraking) { query = query.AsNoTracking(); } if (exp != null) { query = query.Where(exp); } return query; } /// /// 首先在内存中查找,其次再找数据库 /// /// /// /// public async ValueTask FindAsync(Guid id) where T : Entity { return await _dbContext.Set().FindAsync(id).ConfigureAwait(false); } #endregion #region 基本添加、更新、删除 异步 public async ValueTask AddAsync(T entity, bool autoSave = false) where T : Entity { await _dbContext.Set().AddAsync(entity).ConfigureAwait(false); if (autoSave) { await SaveChangesAsync(); } return entity; } public async Task AddRangeAsync(IEnumerable entities, bool autoSave = false) where T : Entity { await _dbContext.Set().AddRangeAsync(entities).ConfigureAwait(false); if (autoSave) { return await SaveChangesAsync(); } else { return false; } } public async Task UpdateRange(IEnumerable entities, bool autoSave = false) where T : Entity { _dbContext.Set().UpdateRange(entities); if (autoSave) { await SaveChangesAsync(); } } public async Task UpdateAsync(T entity, bool autoSave = false) where T : Entity { _dbContext.Set().Update(entity); if (autoSave) { return await SaveChangesAsync(); } else { return false; } } public async Task DeleteAsync(T entity, bool autoSave = false) where T : Entity { _dbContext.Set().Remove(entity); if (autoSave) { return await SaveChangesAsync(); } else { return false; } } public async Task DeleteManyAsync(IEnumerable entities, bool autoSave = false) where T : Entity { _dbContext.Set().RemoveRange(entities); if (autoSave) { return await SaveChangesAsync(); } else { return false; } } public async Task SaveChangesAsync() { return await _dbContext.SaveChangesAsync().ConfigureAwait(false) > 0; } #endregion public async Task DeleteFromQueryAsync(Expression> deleteFilter) where T : Entity { if (deleteFilter == null) throw new ArgumentNullException(nameof(deleteFilter)); return await _dbContext.Set().AsNoTracking().Where(deleteFilter).DeleteFromQueryAsync().ConfigureAwait(false) > 0; } public async Task UpdateFromQueryAsync(Expression> whereFilter, Expression> updateFactory) where T : Entity { if (whereFilter == null) throw new ArgumentNullException(nameof(whereFilter)); return await _dbContext.Set().AsNoTracking().IgnoreQueryFilters().Where(whereFilter).UpdateFromQueryAsync(updateFactory).ConfigureAwait(false) > 0; } } #endregion }