using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; 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 IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure.Extention; namespace IRaCIS.Core.Infra.EFCore { public class Repository : IRepository where TEntity : Entity { public IMapper _mapper { get; set; } public IRaCISDBContext _dbContext { get; set; } private DbSet _dbSet => _dbContext.Set(); public Repository(IRaCISDBContext dbContext, IMapper mapper) { _dbContext = dbContext; _mapper = mapper; } #region 异步部分 public async Task InsertOrUpdateAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) { var entity = _mapper.Map(from); if (entity.Id == Guid.Empty) { foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyUpdate && t.IsVerify)) { if (await _dbSet.AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) { throw new BusinessValidationFailedException(verifyItem.VerifyMsg); } } await _dbSet.AddAsync(entity).ConfigureAwait(false); if (autoSave) { await SaveChangesAsync(); } return entity; } else { foreach (var verifyItem in verify.Where(t => t.verifyType != VerifyEnum.OnlyAdd && t.IsVerify)) { if (verifyItem.verifyType == VerifyEnum.OnlyUpdate) { if (await _dbSet.AnyAsync(verifyItem.VerifyExp).ConfigureAwait(false)) { throw new BusinessValidationFailedException(verifyItem.VerifyMsg); } } else if (verifyItem.verifyType == VerifyEnum.Both) { if (await _dbSet.AnyAsync(verifyItem.VerifyExp.And(t => t.Id != entity.Id)).ConfigureAwait(false)) { throw new BusinessValidationFailedException(verifyItem.VerifyMsg); } } } var dbEntity = await _dbSet.FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false); var dbBeforEntity = dbEntity.Clone(); _mapper.Map(from, dbEntity); if (autoSave) { await SaveChangesAsync(); } return dbBeforEntity; } } public async Task SaveChangesAsync(CancellationToken cancellationToken = default) { return await _dbContext.SaveChangesAsync(cancellationToken) > 0; } public async ValueTask FindAsync(Guid id, CancellationToken cancellationToken = default) { return await _dbContext.FindAsync(id); } //有可能是联合主键,本项目没用到,用Guid public async ValueTask FindAsync(object[] keyValues, CancellationToken cancellationToken) { return await _dbContext.FindAsync(keyValues); } public async Task FirstOrDefaultAsync(Expression> 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 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 AddRangeAsync(IEnumerable 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 UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) { _dbSet.Update(entity); if (autoSave) { return await SaveChangesAsync(cancellationToken); } else { return false; } } public async Task UpdateManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) { _dbSet.UpdateRange(entities); if (autoSave) { return await SaveChangesAsync(cancellationToken); } else { return false; } } public async Task 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 DeleteManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) { _dbSet.RemoveRange(entities); if (autoSave) { return await SaveChangesAsync(cancellationToken); } else { return false; } } public async Task AnyAsync(Expression> exp, bool ignoreQueryFilters = false) { var query = _dbSet.AsQueryable(); if (ignoreQueryFilters) { query = query.IgnoreQueryFilters(); } return await query.AsNoTracking().AnyAsync(exp); } public async Task CountAsync(Expression> 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); } // Z.EntityFramework.Plus.EFCore public async Task DeleteFromQueryAsync(Expression> deleteFilter) { return await _dbSet.Where(deleteFilter).DeleteFromQueryAsync() > 0; } public async Task UpdateFromQueryAsync(Expression> where, Expression> updateFactory) { return await _dbSet.Where(where).UpdateFromQueryAsync(updateFactory) > 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 AsQueryable( bool ignoreQueryFilters = false) { var query = _dbSet.AsQueryable(); if (ignoreQueryFilters) { query = query.IgnoreQueryFilters(); } return query.AsNoTracking(); } public IQueryable Select(Expression> selector) { return _dbSet.AsNoTracking().Select(selector); } public IQueryable WhereIf(bool condition, Expression> filter) { return condition ? _dbSet.AsNoTracking().Where(filter) : _dbSet.AsNoTracking(); } public IQueryable Where(Expression> exp = null, bool isTraking = false,bool ignoreQueryFilters = false) { IQueryable 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 Attach(TEntity entity) { return _dbSet.Attach(entity); } public void Detached(TEntity t) { _dbContext.Entry(t).State = EntityState.Detached; } // automapper 相关 public IQueryable ProjectTo(IConfigurationProvider configuration, object parameters, params Expression>[] membersToExpand) { return _dbSet.AsNoTracking().ProjectTo(configuration, parameters, membersToExpand); } public IQueryable ProjectTo(IConfigurationProvider configuration, params Expression>[] membersToExpand) { return _dbSet.AsNoTracking().ProjectTo(configuration, membersToExpand); } public IQueryable ProjectTo(IConfigurationProvider configuration, IDictionary parameters, params string[] membersToExpand) { return _dbSet.AsNoTracking().ProjectTo(configuration, parameters, membersToExpand); } #endregion } }