using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; using System.Linq.Expressions; namespace ERP.Framework.WebApi { public class BaseRepository where T : BaseEntity where TDbContext : DbContext { public TDbContext Context; public BaseRepository(TDbContext context) { Context = context; } public T? FirstOrDefault(Expression>? exp = null) { return Filter(exp).FirstOrDefault(); } public Task FirstOrDefaultAsync(Expression>? exp = null) { return Filter(exp).FirstOrDefaultAsync(); } public List List(Expression>? exp = null) { return Filter(exp).ToList(); } public void Add(T entity) { Context.Set().Add(entity); Save(); // EF不再跟踪实体更改 Context.Entry(entity).State = EntityState.Detached; } public async Task AddAsync(T entity) { await Context.Set().AddAsync(entity); return await TaskSave(); } public void Save() { try { var entities = Context.ChangeTracker.Entries() .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified) .Select(e => e.Entity); foreach (var entity in entities) { var validationContext = new ValidationContext(entity); Validator.ValidateObject(entity, validationContext, validateAllProperties: true); } Context.SaveChanges(); } catch (ValidationException exc) { // Todo 抛出异常 //Console.WriteLine($"{nameof(Save)} validation exception: {exc?.Message}"); //throw (exc.InnerException as Exception ?? exc); } catch (Exception ex) //DbUpdateException { // Todo 抛出异常 //throw (ex.InnerException as Exception ?? ex); } } public Task TaskSave() { try { var entities = Context.ChangeTracker.Entries() .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified) .Select(e => e.Entity); foreach (var entity in entities) { var validationContext = new ValidationContext(entity); Validator.ValidateObject(entity, validationContext, validateAllProperties: true); } var result = Context.SaveChanges(); return Task.FromResult(result > 0); } catch (Exception ex) { // Todo 打印日志 return Task.FromResult(false); ; } } private IQueryable Filter(Expression>? exp) { var dbSet = Context.Set().AsNoTracking().AsQueryable(); if (exp != null) dbSet = dbSet.Where(exp); return dbSet; } } }