using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; namespace FreeSql { public abstract class BaseRepository : IRepository where TEntity : class { protected IFreeSql _fsql; Expression> _filterVal; protected Expression> Filter { get => _filterVal; set { _filterVal = value; FilterCompile = value?.Compile(); } } internal Expression> FilterInternal => Filter; protected Func FilterCompile { get; private set; } internal Func FilterCompileInternal => FilterCompile; Func _asTableVal; protected Func AsTable { get => _asTableVal; set { _asTableVal = value; AsTableSelect = value == null ? null : new Func((a, b) => a == EntityType ? value(b) : null); } } protected Func AsTableSelect { get; private set; } internal Func AsTableSelectInternal => AsTableSelect; protected Type EntityType { get; } = typeof(TEntity); protected BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base() { _fsql = fsql ?? throw new NullReferenceException("fsql 参数不可为空"); Filter = filter; AsTable = asTable; } public ISelect Select => _fsql.Select().Where(Filter).AsTable(AsTableSelect); public IUpdate UpdateDiy => _fsql.Update().Where(Filter).AsTable(AsTable); public int Delete(Expression> predicate) => _fsql.Delete().Where(Filter).Where(predicate).AsTable(AsTable).ExecuteAffrows(); public int Delete(TEntity entity) { ValidatorEntityAndThrow(entity); return _fsql.Delete(entity).Where(Filter).AsTable(AsTable).ExecuteAffrows(); } public Task DeleteAsync(Expression> predicate) => _fsql.Delete().Where(Filter).Where(predicate).AsTable(AsTable).ExecuteAffrowsAsync(); public Task DeleteAsync(TEntity entity) { ValidatorEntityAndThrow(entity); return _fsql.Delete(entity).Where(Filter).AsTable(AsTable).ExecuteAffrowsAsync(); } public virtual TEntity Insert(TEntity entity) { ValidatorEntityAndThrow(entity); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: return _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteInserted().FirstOrDefault(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: default: throw new NotImplementedException($"{_fsql.Ado.DataType}不支持类似returning或output类型的特性,请参考FreeSql插入数据的方法重新实现。"); } } public virtual List Insert(IEnumerable entitys) { ValidatorEntityAndThrow(entitys); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: return _fsql.Insert().AppendData(entitys).AsTable(AsTable).ExecuteInserted(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: default: throw new NotImplementedException($"{_fsql.Ado.DataType}不支持类似returning或output类型的特性,请参考FreeSql插入数据的方法重新实现。"); } } async public virtual Task InsertAsync(TEntity entity) { ValidatorEntityAndThrow(entity); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: return (await _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteInsertedAsync()).FirstOrDefault(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: default: throw new NotImplementedException($"{_fsql.Ado.DataType}不支持类似returning或output类型的特性,请参考FreeSql插入数据的方法重新实现。"); } } public virtual Task> InsertAsync(IEnumerable entitys) { ValidatorEntityAndThrow(entitys); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: return _fsql.Insert().AppendData(entitys).AsTable(AsTable).ExecuteInsertedAsync(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: default: throw new NotImplementedException($"{_fsql.Ado.DataType}不支持类似returning或output类型的特性,请参考FreeSql插入数据的方法重新实现。"); } } public int Update(TEntity entity) { ValidatorEntityAndThrow(entity); return _fsql.Update().SetSource(entity).Where(Filter).AsTable(AsTable).ExecuteAffrows(); } public Task UpdateAsync(TEntity entity) { ValidatorEntityAndThrow(entity); return _fsql.Update().SetSource(entity).Where(Filter).AsTable(AsTable).ExecuteAffrowsAsync(); } protected void ValidatorEntityAndThrow(TEntity entity) => ValidatorEntityAndThrow(new[] { entity }); protected virtual void ValidatorEntityAndThrow(IEnumerable entitys) { foreach (var entity in entitys) { if (FilterCompile?.Invoke(entity) == false) throw new Exception($"FreeSql.Repository Insert 失败,因为设置了 {Filter},插入的数据不符合"); } } } public abstract class BaseRepository : BaseRepository, IRepository where TEntity : class { public BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base(fsql, filter, asTable) { } public int Delete(TKey id) => _fsql.Delete(id).Where(Filter).AsTable(AsTable).ExecuteAffrows(); public Task DeleteAsync(TKey id) => _fsql.Delete(id).Where(Filter).AsTable(AsTable).ExecuteAffrowsAsync(); public TEntity Find(TKey id) => _fsql.Select(id).Where(Filter).AsTable(AsTableSelect).ToOne(); public Task FindAsync(TKey id) => _fsql.Select(id).Where(Filter).AsTable(AsTableSelect).ToOneAsync(); public TEntity Get(TKey id) => Find(id); public Task GetAsync(TKey id) => FindAsync(id); } }