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

362 lines
11 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.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<TEntity> : IRepository<TEntity>
where TEntity : Entity
{
public IMapper _mapper { get; set; }
public IRaCISDBContext _dbContext { get; set; }
private DbSet<TEntity> _dbSet => _dbContext.Set<TEntity>();
public Repository(IRaCISDBContext dbContext, IMapper mapper)
{
_dbContext = dbContext;
_mapper = mapper;
}
#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)
{
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<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<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> UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
_dbSet.UpdateRange(entities);
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> DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
_dbSet.RemoveRange(entities);
if (autoSave)
{
return await SaveChangesAsync(cancellationToken);
}
else
{
return false;
}
}
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);
}
// Z.EntityFramework.Plus.EFCore
public async Task<bool> DeleteFromQueryAsync(Expression<Func<TEntity, bool>> deleteFilter)
{
return await _dbSet.Where(deleteFilter).DeleteFromQueryAsync() > 0;
}
public async Task<bool> UpdateFromQueryAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> 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<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);
}
#endregion
}
}