From be5259dd685fb77c88469eca1e88772c91169e65 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 1 Apr 2019 10:48:39 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20FreeSql.DbContext=EF=BC=8C?= =?UTF-8?q?=E6=88=90=E4=B8=BA=E7=8B=AC=E7=AB=8B=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/orm_vs/Program.cs | 6 - Examples/orm_vs/orm_vs.csproj | 1 - FreeSql.DbContext/DbContext/DbContext.cs | 87 ------- FreeSql.DbContext/DbContext/DbContextAsync.cs | 118 ---------- .../DbContext/DbContextOptionsBuilder.cs | 18 -- FreeSql.DbContext/DbContext/DbContextSync.cs | 117 ---------- FreeSql.DbContext/DbSet/DbSet.cs | 215 ------------------ FreeSql.DbContext/DbSet/DbSetAsync.cs | 158 ------------- FreeSql.DbContext/DbSet/DbSetSync.cs | 183 --------------- .../Extenssions/DependencyInjection.cs | 24 -- FreeSql.DbContext/FreeSql.DbContext.csproj | 17 -- .../ContextSet/RepositoryDbContext.cs | 25 -- .../Repository/ContextSet/RepositoryDbSet.cs | 60 ----- .../ContextSet/RepositoryUnitOfWork.cs | 45 ---- .../Repository/DataFilter/DataFilter.cs | 153 ------------- .../Repository/DataFilter/DataFilterUtil.cs | 90 -------- .../Extenssions/DependencyInjection.cs | 39 ---- .../FreeSqlRepositoryExtenssions.cs | 58 ----- .../Repository/Repository/BaseRepository.cs | 143 ------------ .../Repository/DefaultRepository.cs | 19 -- .../Repository/Repository/GuidRepository.cs | 19 -- .../Repository/Repository/IBasicRepository.cs | 32 --- .../Repository/IReadOnlyRepository.cs | 27 --- .../Repository/Repository/IRepository.cs | 22 -- FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs | 16 -- FreeSql.DbContext/UnitOfWork/UnitOfWork.cs | 73 ------ FreeSql.Tests/FreeSql.Tests.csproj | 2 +- FreeSql.Tests/UnitTest1.cs | 22 +- FreeSql.sln | 31 +-- FreeSql/Extensions/EntityUtilExtensions.cs | 31 +++ FreeSql/FreeSql.MySql.csproj | 44 ---- FreeSql/FreeSql.csproj | 2 +- 32 files changed, 35 insertions(+), 1862 deletions(-) delete mode 100644 FreeSql.DbContext/DbContext/DbContext.cs delete mode 100644 FreeSql.DbContext/DbContext/DbContextAsync.cs delete mode 100644 FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs delete mode 100644 FreeSql.DbContext/DbContext/DbContextSync.cs delete mode 100644 FreeSql.DbContext/DbSet/DbSet.cs delete mode 100644 FreeSql.DbContext/DbSet/DbSetAsync.cs delete mode 100644 FreeSql.DbContext/DbSet/DbSetSync.cs delete mode 100644 FreeSql.DbContext/Extenssions/DependencyInjection.cs delete mode 100644 FreeSql.DbContext/FreeSql.DbContext.csproj delete mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs delete mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs delete mode 100644 FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs delete mode 100644 FreeSql.DbContext/Repository/DataFilter/DataFilter.cs delete mode 100644 FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs delete mode 100644 FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs delete mode 100644 FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/BaseRepository.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/DefaultRepository.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/GuidRepository.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/IBasicRepository.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs delete mode 100644 FreeSql.DbContext/Repository/Repository/IRepository.cs delete mode 100644 FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs delete mode 100644 FreeSql.DbContext/UnitOfWork/UnitOfWork.cs delete mode 100644 FreeSql/FreeSql.MySql.csproj diff --git a/Examples/orm_vs/Program.cs b/Examples/orm_vs/Program.cs index 344074dd..770b9a16 100644 --- a/Examples/orm_vs/Program.cs +++ b/Examples/orm_vs/Program.cs @@ -41,12 +41,6 @@ namespace orm_vs //optionsBuilder.UseMySql("Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Min Pool Size=21;Max Pool Size=21"); } } - class FreeSongContext: FreeSql.DbContext { - public FreeSql.DbSet Songs { get; set; } - protected override void OnConfiguring(FreeSql.DbContextOptionsBuilder builder) { - builder.UseFreeSql(fsql); - } - } static void Main(string[] args) { diff --git a/Examples/orm_vs/orm_vs.csproj b/Examples/orm_vs/orm_vs.csproj index 5ef35aed..81b0c501 100644 --- a/Examples/orm_vs/orm_vs.csproj +++ b/Examples/orm_vs/orm_vs.csproj @@ -12,7 +12,6 @@ - diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs deleted file mode 100644 index 29d66e23..00000000 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ /dev/null @@ -1,87 +0,0 @@ -using SafeObjectPool; -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Data.Common; -using System.Linq; -using System.Reflection; -using System.Linq.Expressions; - -namespace FreeSql { - public abstract partial class DbContext : IDisposable { - - internal IFreeSql _orm; - internal IFreeSql _fsql => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); - - IUnitOfWork _uowPriv; - internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(_fsql))) : null; - internal bool _isUseUnitOfWork = true; //不使用工作单元事务 - - static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); - protected DbContext() { - - var builder = new DbContextOptionsBuilder(); - OnConfiguring(builder); - _orm = builder._fsql; - - var props = _dicGetDbSetProps.GetOrAdd(this.GetType(), tp => - tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public) - .Where(a => a.PropertyType.IsGenericType && - a.PropertyType == typeof(DbSet<>).MakeGenericType(a.PropertyType.GenericTypeArguments[0])).ToArray()); - - foreach (var prop in props) { - var set = this.Set(prop.PropertyType.GenericTypeArguments[0]); - - prop.SetValue(this, set); - AllSets.Add(prop.Name, set); - } - } - - protected virtual void OnConfiguring(DbContextOptionsBuilder builder) { - - } - - - protected Dictionary _dicSet = new Dictionary(); - public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; - public virtual object Set(Type entityType) { - if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; - var sd = Activator.CreateInstance(typeof(DbContextDbSet<>).MakeGenericType(entityType), this); - _dicSet.Add(entityType, sd); - return sd; - } - protected Dictionary AllSets { get; } = new Dictionary(); - - internal class ExecCommandInfo { - public ExecCommandInfoType actionType { get; set; } - public object dbSet { get; set; } - public Type stateType { get; set; } - public object state { get; set; } - } - internal enum ExecCommandInfoType { Insert, Update, Delete } - Queue _actions = new Queue(); - internal int _affrows = 0; - - internal void EnqueueAction(ExecCommandInfoType actionType, object dbSet, Type stateType, object state) { - _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); - } - - ~DbContext() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - _actions.Clear(); - _dicSet.Clear(); - AllSets.Clear(); - - _uow?.Rollback(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } - } -} diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs deleted file mode 100644 index bf2d2134..00000000 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ /dev/null @@ -1,118 +0,0 @@ -using SafeObjectPool; -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Data.Common; -using System.Linq; -using System.Reflection; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql { - partial class DbContext { - - async public Task SaveChangesAsync() { - await ExecCommandAsync(); - _uow?.Commit(); - var ret = _affrows; - _affrows = 0; - return ret; - } - - static Dictionary>>> _dicExecCommandDbContextBetchAsync = new Dictionary>>>(); - async internal Task ExecCommandAsync() { - if (_actions.Any() == false) return; - ExecCommandInfo oldinfo = null; - var states = new List(); - - Func> dbContextBetch = methodName => { - if (_dicExecCommandDbContextBetchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - - var returnTarget = Expression.Label(typeof(Task)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(int))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } - return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Func funcDelete = async () => { - _affrows += await dbContextBetch("DbContextBetchRemoveAsync"); - states.Clear(); - }; - Func funcInsert = async () => { - _affrows += await dbContextBetch("DbContextBetchAddAsync"); - states.Clear(); - }; - Func funcUpdate = async (isLiveUpdate) => { - var affrows = 0; - if (isLiveUpdate) affrows = await dbContextBetch("DbContextBetchUpdateNowAsync"); - else affrows = await dbContextBetch("DbContextBetchUpdateAsync"); - if (affrows == -999) { //最后一个元素已被删除 - states.RemoveAt(states.Count - 1); - return; - } - if (affrows == -998 || affrows == -997) { //没有执行更新 - var laststate = states[states.Count - 1]; - states.Clear(); - if (affrows == -997) states.Add(laststate); //保留最后一个 - } - if (affrows > 0) { - _affrows += affrows; - var islastNotUpdated = states.Count != affrows; - var laststate = states[states.Count - 1]; - states.Clear(); - if (islastNotUpdated) states.Add(laststate); //保留最后一个 - } - }; - - while (_actions.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; - if (oldinfo == null) oldinfo = info; - var isLiveUpdate = false; - - if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) { - - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { - //最后一个,合起来发送 - states.Add(info.state); - info = null; - } - - switch (oldinfo.actionType) { - case ExecCommandInfoType.Insert: - await funcInsert(); - break; - case ExecCommandInfoType.Delete: - await funcDelete(); - break; - } - isLiveUpdate = true; - } - - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { - if (states.Any()) - await funcUpdate(isLiveUpdate); - } - - if (info != null) { - states.Add(info.state); - oldinfo = info; - } - } - } - } -} diff --git a/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs b/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs deleted file mode 100644 index 793336f4..00000000 --- a/FreeSql.DbContext/DbContext/DbContextOptionsBuilder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Text; - -namespace FreeSql { - public class DbContextOptionsBuilder { - - internal IFreeSql _fsql; - - public DbContextOptionsBuilder UseFreeSql(IFreeSql orm) { - _fsql = orm; - return this; - } - } -} diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs deleted file mode 100644 index ced1304a..00000000 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ /dev/null @@ -1,117 +0,0 @@ -using SafeObjectPool; -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Data.Common; -using System.Linq; -using System.Reflection; -using System.Linq.Expressions; - -namespace FreeSql { - partial class DbContext { - - public int SaveChanges() { - ExecCommand(); - _uow?.Commit(); - var ret = _affrows; - _affrows = 0; - return ret; - } - - static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); - internal void ExecCommand() { - if (_actions.Any() == false) return; - ExecCommandInfo oldinfo = null; - var states = new List(); - - Func dbContextBetch = methodName => { - if (_dicExecCommandDbContextBetch.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - - var returnTarget = Expression.Label(typeof(int)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(int))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } - return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Action funcDelete = () => { - _affrows += dbContextBetch("DbContextBetchRemove"); - states.Clear(); - }; - Action funcInsert = () => { - _affrows += dbContextBetch("DbContextBetchAdd"); - states.Clear(); - }; - Action funcUpdate = isLiveUpdate => { - var affrows = 0; - if (isLiveUpdate) affrows = dbContextBetch("DbContextBetchUpdateNow"); - else affrows = dbContextBetch("DbContextBetchUpdate"); - if (affrows == -999) { //最后一个元素已被删除 - states.RemoveAt(states.Count - 1); - return; - } - if (affrows == -998 || affrows == -997) { //没有执行更新 - var laststate = states[states.Count - 1]; - states.Clear(); - if (affrows == -997) states.Add(laststate); //保留最后一个 - } - if (affrows > 0) { - _affrows += affrows; - var islastNotUpdated = states.Count != affrows; - var laststate = states[states.Count - 1]; - states.Clear(); - if (islastNotUpdated) states.Add(laststate); //保留最后一个 - } - }; - - while (_actions.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; - if (oldinfo == null) oldinfo = info; - var isLiveUpdate = false; - - if (_actions.Any() == false && states.Any() || - info != null && oldinfo.actionType != info.actionType || - info != null && oldinfo.stateType != info.stateType) { - - if (info != null && oldinfo.actionType == info.actionType && oldinfo.stateType == info.stateType) { - //最后一个,合起来发送 - states.Add(info.state); - info = null; - } - - switch (oldinfo.actionType) { - case ExecCommandInfoType.Insert: - funcInsert(); - break; - case ExecCommandInfoType.Delete: - funcDelete(); - break; - } - isLiveUpdate = true; - } - - if (isLiveUpdate || oldinfo.actionType == ExecCommandInfoType.Update) { - if (states.Any()) - funcUpdate(isLiveUpdate); - } - - if (info != null) { - states.Add(info.state); - oldinfo = info; - } - } - } - } -} diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs deleted file mode 100644 index 7b2028b8..00000000 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ /dev/null @@ -1,215 +0,0 @@ -using FreeSql.Extensions.EntityUtil; -using FreeSql.Internal.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; - -namespace FreeSql { - - internal class DbContextDbSet : DbSet where TEntity : class { - - public DbContextDbSet(DbContext ctx) { - _ctx = ctx; - _uow = ctx._uow; - _fsql = ctx._fsql; - } - } - - public abstract partial class DbSet : IDisposable where TEntity : class { - - internal DbContext _ctx; - internal IUnitOfWork _uow; - internal IFreeSql _fsql; - - protected virtual ISelect OrmSelect(object dywhere) { - DbContextExecCommand(); //查询前先提交,否则会出脏读 - return _fsql.Select(dywhere).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList); - } - - ~DbSet() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - this._dicUpdateTimes.Clear(); - this._states.Clear(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } - - protected virtual IInsert OrmInsert() => _fsql.Insert().WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IInsert OrmInsert(TEntity data) => _fsql.Insert(data).WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IInsert OrmInsert(IEnumerable data) => _fsql.Insert(data).WithTransaction(_uow?.GetOrBeginTransaction()); - - protected virtual IUpdate OrmUpdate(IEnumerable entitys) => _fsql.Update().SetSource(entitys).WithTransaction(_uow?.GetOrBeginTransaction()); - protected virtual IDelete OrmDelete(object dywhere) => _fsql.Delete(dywhere).WithTransaction(_uow?.GetOrBeginTransaction()); - - internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) { - _ctx.EnqueueAction(actionType, this, typeof(EntityState), state); - } - internal void IncrAffrows(int affrows) { - _ctx._affrows += affrows; - } - internal void TrackToList(object list) { - if (list == null) return; - var ls = list as IList; - if (ls == null) return; - - foreach (var item in ls) { - var key = _fsql.GetEntityKeyString(item); - if (_states.ContainsKey(key)) { - _fsql.MapEntityValue(item, _states[key].Value); - _states[key].Time = DateTime.Now; - } else { - _states.Add(key, CreateEntityState(item)); - } - } - } - - public ISelect Select => this.OrmSelect(null); - public ISelect Where(Expression> exp) => this.OrmSelect(null).Where(exp); - public ISelect WhereIf(bool condition, Expression> exp) => this.OrmSelect(null).WhereIf(condition, exp); - - protected Dictionary _states = new Dictionary(); - internal Dictionary _statesInternal => _states; - TableInfo _tablePriv; - protected TableInfo _table => _tablePriv ?? (_tablePriv = _fsql.CodeFirst.GetTableByEntity(_entityType)); - ColumnInfo[] _tableIdentitysPriv; - protected ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); - protected Type _entityType = typeof(TEntity); - internal Type _entityTypeInternal => _entityType; - - public class EntityState { - public EntityState(TEntity value, string key) { - this.Value = value; - this.Key = key; - this.Time = DateTime.Now; - } - public TEntity OldValue { get; set; } - public TEntity Value { get; set; } - public string Key { get; set; } - public DateTime Time { get; set; } - } - - #region Utils - EntityState CreateEntityState(TEntity data) { - if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _fsql.GetEntityKeyString(data); - var state = new EntityState(Activator.CreateInstance(), key); - _fsql.MapEntityValue(data, state.Value); - return state; - } - bool ExistsInStates(TEntity data) { - if (data == null) throw new ArgumentNullException(nameof(data)); - var key = _fsql.GetEntityKeyString(data); - if (string.IsNullOrEmpty(key)) return false; - return _states.ContainsKey(key); - } - - bool CanAdd(IEnumerable data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - foreach (var s in data) if (CanAdd(s, isThrow) == false) return false; - return true; - } - bool CanAdd(TEntity data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - var key = _fsql.GetEntityKeyString(data); - if (string.IsNullOrEmpty(key)) { - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - return true; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - return true; - } - if (isThrow) throw new Exception($"不可添加,未设置主键的值:{_fsql.GetEntityString(data)}"); - return false; - } - } else { - if (_states.ContainsKey(key)) { - if (isThrow) throw new Exception($"不可添加,已存在于状态管理:{_fsql.GetEntityString(data)}"); - return false; - } - var idval = _fsql.GetEntityIdentityValueWithPrimary(data); - if (idval > 0) { - if (isThrow) throw new Exception($"不可添加,自增属性有值:{_fsql.GetEntityString(data)}"); - return false; - } - } - return true; - } - - bool CanUpdate(IEnumerable data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - foreach (var s in data) if (CanUpdate(s, isThrow) == false) return false; - return true; - } - bool CanUpdate(TEntity data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可更新,实体没有主键:{_fsql.GetEntityString(data)}"); - return false; - } - var key = _fsql.GetEntityKeyString(data); - if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可更新,未设置主键的值:{_fsql.GetEntityString(data)}"); - return false; - } - if (_states.TryGetValue(key, out var tryval) == false) { - if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询:{_fsql.GetEntityString(data)}"); - return false; - } - return true; - } - - bool CanRemove(IEnumerable data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - foreach (var s in data) if (CanRemove(s, isThrow) == false) return false; - return true; - } - bool CanRemove(TEntity data, bool isThrow) { - if (data == null) { - if (isThrow) throw new ArgumentNullException(nameof(data)); - return false; - } - if (_table.Primarys.Any() == false) { - if (isThrow) throw new Exception($"不可删除,实体没有主键:{_fsql.GetEntityString(data)}"); - return false; - } - var key = _fsql.GetEntityKeyString(data); - if (string.IsNullOrEmpty(key)) { - if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_fsql.GetEntityString(data)}"); - return false; - } - //if (_states.TryGetValue(key, out var tryval) == false) { - // if (isThrow) throw new Exception($"不可删除,数据未被跟踪,应该先查询:{_fsql.GetEntityString(data)}"); - // return false; - //} - return true; - } - #endregion - } -} diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs deleted file mode 100644 index c17c0724..00000000 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ /dev/null @@ -1,158 +0,0 @@ -using FreeSql.Extensions.EntityUtil; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace FreeSql { - partial class DbSet { - - Task DbContextExecCommandAsync() { - _dicUpdateTimes.Clear(); - return _ctx.ExecCommandAsync(); - } - - async Task DbContextBetchAddAsync(EntityState[] adds) { - if (adds.Any() == false) return 0; - var affrows = await this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrowsAsync(); - return affrows; - } - - #region Add - async Task AddPrivAsync(TEntity data, bool isCheck) { - if (isCheck && CanAdd(data, true) == false) return; - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); - var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(data, idtval); - var state = CreateEntityState(data); - _states.Add(state.Key, state); - } else { - await DbContextExecCommandAsync(); - var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); - IncrAffrows(1); - _fsql.MapEntityValue(newval, data); - var state = CreateEntityState(newval); - _states.Add(state.Key, state); - } - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); - var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(data, idtval); - var state = CreateEntityState(data); - _states.Add(state.Key, state); - } - return; - } - } else { - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); - } - } - public Task AddAsync(TEntity data) => AddPrivAsync(data, true); - async public Task AddRangeAsync(IEnumerable data) { - if (CanAdd(data, true) == false) return; - if (data.ElementAtOrDefault(1) == default(TEntity)) { - await AddAsync(data.First()); - return; - } - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - await DbContextExecCommandAsync(); - var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); - var idx = 0; - foreach (var s in data) - _fsql.MapEntityValue(rets[idx++], s); - IncrAffrows(rets.Count); - TrackToList(rets); - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - foreach (var s in data) - await AddPrivAsync(s, false); - return; - } - } else { - //进入队列,等待 SaveChanges 时执行 - foreach (var item in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); - } - } - #endregion - - #region UpdateAsync - Task DbContextBetchUpdateAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, false); - Task DbContextBetchUpdateNowAsync(EntityState[] ups) => DbContextBetchUpdatePrivAsync(ups, true); - async Task DbContextBetchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate) { - if (ups.Any() == false) return 0; - var uplst1 = ups[ups.Length - 1]; - var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; - - if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; - var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(uplst2.Value)}"); - - var cuig1 = _fsql.CompareEntityValueReturnColumns(uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(uplst2.Value, lstval2.Value, true) : null; - - List data = null; - string[] cuig = null; - if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { - //最后一个不保存 - data = ups.ToList(); - data.RemoveAt(ups.Length - 1); - cuig = cuig2; - } else if (isLiveUpdate) { - //立即保存 - data = ups.ToList(); - cuig = cuig1; - } - - if (data?.Count > 0) { - - if (cuig.Length == _table.Columns.Count) - return ups.Length == data.Count ? -998 : -997; - - var updateSource = data.Select(a => a.Value).ToArray(); - var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); - - var affrows = await update.ExecuteAffrowsAsync(); - - foreach (var newval in data) { - if (_states.TryGetValue(newval.Key, out var tryold)) - _fsql.MapEntityValue(newval.Value, tryold.Value); - if (newval.OldValue != null) - _fsql.MapEntityValue(newval.Value, newval.OldValue); - } - return affrows; - } - - //等待下次对比再保存 - return 0; - } - #endregion - - #region RemoveAsync - async Task DbContextBetchRemoveAsync(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); - return Math.Max(dels.Length, affrows); - } - #endregion - } -} diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs deleted file mode 100644 index 95697bef..00000000 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ /dev/null @@ -1,183 +0,0 @@ -using FreeSql.Extensions.EntityUtil; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace FreeSql { - partial class DbSet { - - void DbContextExecCommand() { - _dicUpdateTimes.Clear(); - _ctx.ExecCommand(); - } - - int DbContextBetchAdd(EntityState[] adds) { - if (adds.Any() == false) return 0; - var affrows = this.OrmInsert(adds.Select(a => a.Value)).ExecuteAffrows(); - return affrows; - } - - #region Add - void AddPriv(TEntity data, bool isCheck) { - if (isCheck && CanAdd(data, true) == false) return; - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - DbContextExecCommand(); - var idtval = this.OrmInsert(data).ExecuteIdentity(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(data, idtval); - var state = CreateEntityState(data); - _states.Add(state.Key, state); - } else { - DbContextExecCommand(); - var newval = this.OrmInsert(data).ExecuteInserted().First(); - IncrAffrows(1); - _fsql.MapEntityValue(newval, data); - var state = CreateEntityState(newval); - _states.Add(state.Key, state); - } - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - DbContextExecCommand(); - var idtval = this.OrmInsert(data).ExecuteIdentity(); - IncrAffrows(1); - _fsql.SetEntityIdentityValueWithPrimary(data, idtval); - var state = CreateEntityState(data); - _states.Add(state.Key, state); - } - return; - } - } else - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); - } - public void Add(TEntity data) => AddPriv(data, true); - public void AddRange(IEnumerable data) { - if (CanAdd(data, true) == false) return; - if (data.ElementAtOrDefault(1) == default(TEntity)) { - Add(data.First()); - return; - } - if (_tableIdentitys.Length > 0) { - //有自增,马上执行 - switch (_fsql.Ado.DataType) { - case DataType.SqlServer: - case DataType.PostgreSQL: - DbContextExecCommand(); - var rets = this.OrmInsert(data).ExecuteInserted(); - if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_fsql.Ado.DataType} 的返回数据,与添加的数目不匹配"); - var idx = 0; - foreach (var s in data) - _fsql.MapEntityValue(rets[idx++], s); - IncrAffrows(rets.Count); - TrackToList(rets); - return; - case DataType.MySql: - case DataType.Oracle: - case DataType.Sqlite: - foreach (var s in data) - AddPriv(s, false); - return; - } - } else { - //进入队列,等待 SaveChanges 时执行 - foreach (var item in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(item)); - } - } - #endregion - - #region Update - int DbContextBetchUpdate(EntityState[] ups) => DbContextBetchUpdatePriv(ups, false); - int DbContextBetchUpdateNow(EntityState[] ups) => DbContextBetchUpdatePriv(ups, true); - int DbContextBetchUpdatePriv(EntityState[] ups, bool isLiveUpdate) { - if (ups.Any() == false) return 0; - var uplst1 = ups[ups.Length - 1]; - var uplst2 = ups.Length > 1 ? ups[ups.Length - 2] : null; - - if (_states.TryGetValue(uplst1.Key, out var lstval1) == false) return -999; - var lstval2 = default(EntityState); - if (uplst2 != null && _states.TryGetValue(uplst2.Key, out lstval2) == false) throw new Exception($"特别错误:更新失败,数据未被跟踪:{_fsql.GetEntityString(uplst2.Value)}"); - - var cuig1 = _fsql.CompareEntityValueReturnColumns(uplst1.Value, lstval1.Value, true); - var cuig2 = uplst2 != null ? _fsql.CompareEntityValueReturnColumns(uplst2.Value, lstval2.Value, true) : null; - - List data = null; - string[] cuig = null; - if (uplst2 != null && string.Compare(string.Join(",", cuig1), string.Join(",", cuig2)) != 0) { - //最后一个不保存 - data = ups.ToList(); - data.RemoveAt(ups.Length - 1); - cuig = cuig2; - } else if (isLiveUpdate) { - //立即保存 - data = ups.ToList(); - cuig = cuig1; - } - - if (data?.Count > 0) { - - if (cuig.Length == _table.Columns.Count) - return ups.Length == data.Count ? -998 : -997; - - var updateSource = data.Select(a => a.Value).ToArray(); - var update = this.OrmUpdate(null).SetSource(updateSource).IgnoreColumns(cuig); - - var affrows = update.ExecuteAffrows(); - - foreach (var newval in data) { - if (_states.TryGetValue(newval.Key, out var tryold)) - _fsql.MapEntityValue(newval.Value, tryold.Value); - if (newval.OldValue != null) - _fsql.MapEntityValue(newval.Value, newval.OldValue); - } - return affrows; - } - - //等待下次对比再保存 - return 0; - } - - Dictionary _dicUpdateTimes = new Dictionary(); - public void Update(TEntity data) => UpdateRange(new[] { data }); - public void UpdateRange(IEnumerable data) { - if (CanUpdate(data, true) == false) return; - foreach (var item in data) { - if (_dicUpdateTimes.ContainsKey(item)) - DbContextExecCommand(); - _dicUpdateTimes.Add(item, 1); - - var state = CreateEntityState(item); - state.OldValue = item; - EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); - } - } - #endregion - - #region Remove - int DbContextBetchRemove(EntityState[] dels) { - if (dels.Any() == false) return 0; - var affrows = this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrows(); - return Math.Max(dels.Length, affrows); - } - - public void Remove(TEntity data) => RemoveRange(new[] { data }); - public void RemoveRange(IEnumerable data) { - if (CanRemove(data, true) == false) return; - foreach (var item in data) { - var state = CreateEntityState(item); - if (_states.ContainsKey(state.Key)) _states.Remove(state.Key); - _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(item); - - EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); - } - } - #endregion - } -} diff --git a/FreeSql.DbContext/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Extenssions/DependencyInjection.cs deleted file mode 100644 index 75cbf032..00000000 --- a/FreeSql.DbContext/Extenssions/DependencyInjection.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System; - -namespace FreeSql { - public static class DbContextDependencyInjection { - - public static IServiceCollection AddFreeDbContext(this IServiceCollection services, Action options) where TDbContext : DbContext { - - services.AddScoped(sp => { - var ctx = Activator.CreateInstance(); - - if (ctx._orm == null) { - var builder = new DbContextOptionsBuilder(); - options(builder); - ctx._orm = builder._fsql; - } - - return ctx; - }); - - return services; - } - } -} diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj deleted file mode 100644 index d11a846c..00000000 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - netstandard2.0 - 0.3.27.1 - true - YeXiangQin - FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. - https://github.com/2881099/FreeSql - FreeSql ORM - - - - - - - diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs deleted file mode 100644 index b4460bfe..00000000 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace FreeSql { - internal class RepositoryDbContext : DbContext where TEntity : class { - - protected BaseRepository _repos; - public RepositoryDbContext(IFreeSql orm, BaseRepository repos) : base() { - _orm = orm; - _repos = repos; - _isUseUnitOfWork = false; - } - - public override object Set(Type entityType) { - if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; - var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), _repos); - _dicSet.Add(entityType, sd); - return sd; - } - - RepositoryDbSet _dbSet; - public RepositoryDbSet DbSet => _dbSet ?? (_dbSet = Set() as RepositoryDbSet); - } -} diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs deleted file mode 100644 index 63a11ac8..00000000 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs +++ /dev/null @@ -1,60 +0,0 @@ -using FreeSql.Extensions.EntityUtil; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace FreeSql { - internal class RepositoryDbSet : DbSet where TEntity : class { - - protected BaseRepository _repos; - public RepositoryDbSet(BaseRepository repos) { - _ctx = repos._db; - _fsql = repos._fsql; - _uow = repos.UnitOfWork; - _repos = repos; - } - - protected override ISelect OrmSelect(object dywhere) { - var select = base.OrmSelect(dywhere); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) select.Where(filter.Value.Expression); - return select.AsTable(_repos.AsTableSelectInternal); - } - internal ISelect OrmSelectInternal(object dywhere) => OrmSelect(dywhere); - protected override IUpdate OrmUpdate(IEnumerable entitys) { - var update = base.OrmUpdate(entitys); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) { - if (entitys != null) - foreach (var entity in entitys) - if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Update 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},更新的数据不符合 {_fsql.GetEntityString(entity)}"); - update.Where(filter.Value.Expression); - } - return update.AsTable(_repos.AsTableInternal); - } - internal IUpdate OrmUpdateInternal(IEnumerable entitys) => OrmUpdate(entitys); - protected override IDelete OrmDelete(object dywhere) { - var delete = base.OrmDelete(dywhere); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) delete.Where(filter.Value.Expression); - return delete.AsTable(_repos.AsTableInternal); - } - internal IDelete OrmDeleteInternal(object dywhere) => OrmDelete(dywhere); - protected override IInsert OrmInsert(TEntity entity) => OrmInsert(new[] { entity }); - protected override IInsert OrmInsert(IEnumerable entitys) { - var insert = base.OrmInsert(entitys); - var filters = (_repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) { - if (entitys != null) - foreach (var entity in entitys) - if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) - throw new Exception($"FreeSql.Repository Insert 失败,因为设置了过滤器 {filter.Key}: {filter.Value.Expression},插入的数据不符合 {_fsql.GetEntityString(entity)}"); - } - return insert.AsTable(_repos.AsTableInternal); - } - internal IInsert OrmInsertInternal(TEntity entity) => OrmInsert(entity); - internal IInsert OrmInsertInternal(IEnumerable entitys) => OrmInsert(entitys); - } -} diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs deleted file mode 100644 index 4d7ce1e0..00000000 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; - -namespace FreeSql { - - public interface IRepositoryUnitOfWork : IUnitOfWork { - /// - /// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 - /// - /// - /// - /// 数据过滤 + 验证 - /// - DefaultRepository GetRepository(Expression> filter = null) where TEntity : class; - - /// - /// 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点 - /// - /// - /// 数据过滤 + 验证 - /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - /// - GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; - } - - class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork { - - public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) { - } - - public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class { - var repos = new GuidRepository(_fsql, filter, asTable); - repos.UnitOfWork = this; - return repos; - } - - public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class { - var repos = new DefaultRepository(_fsql, filter); - repos.UnitOfWork = this; - return repos; - } - } -} diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs deleted file mode 100644 index 63c435b0..00000000 --- a/FreeSql.DbContext/Repository/DataFilter/DataFilter.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Linq.Expressions; -using System.Text; -using System.Linq; - -namespace FreeSql { - public interface IDataFilter : IDisposable where TEntity : class { - - IDataFilter Apply(string filterName, Expression> filterAndValidateExp); - - /// - /// 开启过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// 过滤器名称 - /// - IDisposable Enable(params string[] filterName); - /// - /// 开启所有过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// - IDisposable EnableAll(); - - /// - /// 禁用过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// - /// - IDisposable Disable(params string[] filterName); - /// - /// 禁用所有过滤器,若使用 using 则使用完后,恢复为原有状态 - /// - /// - IDisposable DisableAll(); - - bool IsEnabled(string filterName); - } - - internal class DataFilter : IDataFilter where TEntity : class { - - internal class FilterItem { - public Expression> Expression { get; set; } - Func _expressionDelegate; - public Func ExpressionDelegate => _expressionDelegate ?? (_expressionDelegate = Expression?.Compile()); - public bool IsEnabled { get; set; } - } - - internal ConcurrentDictionary _filters = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); - public IDataFilter Apply(string filterName, Expression> filterAndValidateExp) { - - if (filterName == null) - throw new ArgumentNullException(nameof(filterName)); - if (filterAndValidateExp == null) return this; - - var filterItem = new FilterItem { Expression = filterAndValidateExp, IsEnabled = true }; - _filters.AddOrUpdate(filterName, filterItem, (k, v) => filterItem); - return this; - } - - public IDisposable Disable(params string[] filterName) { - if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); - - List restore = new List(); - foreach (var name in filterName) { - if (_filters.TryGetValue(name, out var tryfi)) { - if (tryfi.IsEnabled) { - restore.Add(name); - tryfi.IsEnabled = false; - } - } - } - return new UsingAny(() => this.Enable(restore.ToArray())); - } - public IDisposable DisableAll() { - List restore = new List(); - foreach (var val in _filters) { - if (val.Value.IsEnabled) { - restore.Add(val.Key); - val.Value.IsEnabled = false; - } - } - return new UsingAny(() => this.Enable(restore.ToArray())); - } - class UsingAny : IDisposable { - Action _ondis; - public UsingAny(Action ondis) { - _ondis = ondis; - } - public void Dispose() { - _ondis?.Invoke(); - } - } - - public IDisposable Enable(params string[] filterName) { - if (filterName == null || filterName.Any() == false) return new UsingAny(() => { }); - - List restore = new List(); - foreach (var name in filterName) { - if (_filters.TryGetValue(name, out var tryfi)) { - if (tryfi.IsEnabled == false) { - restore.Add(name); - tryfi.IsEnabled = true; - } - } - } - return new UsingAny(() => this.Disable(restore.ToArray())); - } - public IDisposable EnableAll() { - List restore = new List(); - foreach (var val in _filters) { - if (val.Value.IsEnabled == false) { - restore.Add(val.Key); - val.Value.IsEnabled = true; - } - } - return new UsingAny(() => this.Disable(restore.ToArray())); - } - - public bool IsEnabled(string filterName) { - if (filterName == null) return false; - return _filters.TryGetValue(filterName, out var tryfi) ? tryfi.IsEnabled : false; - } - - ~DataFilter() { - this.Dispose(); - } - public void Dispose() { - _filters.Clear(); - } - } - - public class FluentDataFilter : IDisposable { - - internal List<(Type type, string name, LambdaExpression exp)> _filters = new List<(Type type, string name, LambdaExpression exp)>(); - - public FluentDataFilter Apply(string filterName, Expression> filterAndValidateExp) where TEntity : class { - if (filterName == null) - throw new ArgumentNullException(nameof(filterName)); - if (filterAndValidateExp == null) return this; - - _filters.Add((typeof(TEntity), filterName, filterAndValidateExp)); - return this; - } - - ~FluentDataFilter() { - this.Dispose(); - } - public void Dispose() { - _filters.Clear(); - } - } -} diff --git a/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs b/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs deleted file mode 100644 index 77f41a5d..00000000 --- a/FreeSql.DbContext/Repository/DataFilter/DataFilterUtil.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; - -namespace FreeSql { - - internal class DataFilterUtil { - - internal static Action _globalDataFilter; - - static ConcurrentDictionary _dicSetRepositoryDataFilterApplyDataFilterFunc = new ConcurrentDictionary(); - static ConcurrentDictionary> _dicSetRepositoryDataFilterConvertFilterNotExists = new ConcurrentDictionary>(); - internal static void SetRepositoryDataFilter(object repos, Action scopedDataFilter) { - if (scopedDataFilter != null) { - SetRepositoryDataFilter(repos, null); - } - if (scopedDataFilter == null) { - scopedDataFilter = _globalDataFilter; - } - if (scopedDataFilter == null) return; - using (var globalFilter = new FluentDataFilter()) { - scopedDataFilter(globalFilter); - - var type = repos.GetType(); - Type entityType = (repos as IRepository).EntityType; - if (entityType == null) throw new Exception("FreeSql.Repository 设置过滤器失败,原因是对象不属于 IRepository"); - - var notExists = _dicSetRepositoryDataFilterConvertFilterNotExists.GetOrAdd(type, t => new ConcurrentDictionary()); - var newFilter = new Dictionary(); - foreach (var gf in globalFilter._filters) { - if (notExists.ContainsKey(gf.name)) continue; - - LambdaExpression newExp = null; - var filterParameter1 = Expression.Parameter(entityType, gf.exp.Parameters[0].Name); - try { - newExp = Expression.Lambda( - typeof(Func<,>).MakeGenericType(entityType, typeof(bool)), - new ReplaceVisitor().Modify(gf.exp.Body, filterParameter1), - filterParameter1 - ); - } catch { - notExists.TryAdd(gf.name, true); //防止第二次错误 - continue; - } - newFilter.Add(gf.name, newExp); - } - if (newFilter.Any() == false) return; - - var del = _dicSetRepositoryDataFilterApplyDataFilterFunc.GetOrAdd(type, t => { - var reposParameter = Expression.Parameter(type); - var nameParameter = Expression.Parameter(typeof(string)); - var expressionParameter = Expression.Parameter( - typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(entityType, typeof(bool))) - ); - return Expression.Lambda( - Expression.Block( - Expression.Call(reposParameter, type.GetMethod("ApplyDataFilter", BindingFlags.Instance | BindingFlags.NonPublic), nameParameter, expressionParameter) - ), - new[] { - reposParameter, nameParameter, expressionParameter - } - ).Compile(); - }); - foreach (var nf in newFilter) { - del.DynamicInvoke(repos, nf.Key, nf.Value); - } - newFilter.Clear(); - } - } - } - - class ReplaceVisitor : ExpressionVisitor { - private ParameterExpression parameter; - - public Expression Modify(Expression expression, ParameterExpression parameter) { - this.parameter = parameter; - return Visit(expression); - } - - protected override Expression VisitMember(MemberExpression node) { - if (node.Expression?.NodeType == ExpressionType.Parameter) - return Expression.Property(parameter, node.Member.Name); - return base.VisitMember(node); - } - } -} diff --git a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs b/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs deleted file mode 100644 index e258b676..00000000 --- a/FreeSql.DbContext/Repository/Extenssions/DependencyInjection.cs +++ /dev/null @@ -1,39 +0,0 @@ -using FreeSql; -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Linq.Expressions; -using System.Reflection; -using System.Linq; -using Microsoft.Extensions.DependencyInjection; - -namespace FreeSql { - public static class FreeSqlRepositoryDependencyInjection { - - public static IServiceCollection AddFreeRepository(this IServiceCollection services, Action globalDataFilter = null, params Assembly[] assemblies) { - - DataFilterUtil._globalDataFilter = globalDataFilter; - - services.AddScoped(typeof(IReadOnlyRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(IBasicRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>)); - services.AddScoped(typeof(GuidRepository<>)); - - services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(IBasicRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(BaseRepository<,>), typeof(DefaultRepository<,>)); - services.AddScoped(typeof(DefaultRepository<,>)); - - if (assemblies?.Any() == true) { - foreach(var asse in assemblies) { - foreach (var repos in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IRepository).IsAssignableFrom(a))) { - - services.AddScoped(repos); - } - } - } - - return services; - } - } -} \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs deleted file mode 100644 index 4be01be5..00000000 --- a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs +++ /dev/null @@ -1,58 +0,0 @@ -using FreeSql; -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Text; -using System.Linq.Expressions; -using System.Linq; -using System.Data; - -public static class FreeSqlRepositoryExtenssions { - - /// - /// 返回默认仓库类 - /// - /// - /// - /// - /// 数据过滤 + 验证 - /// - public static DefaultRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { - return new DefaultRepository(that, filter); - } - - /// - /// 返回仓库类 - /// - /// - /// - /// 数据过滤 + 验证 - /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - /// - public static GuidRepository GetGuidRepository(this IFreeSql that, Expression> filter = null, Func asTable = null) where TEntity : class { - return new GuidRepository(that, filter, asTable); - } - - /// - /// 合并两个仓储的设置(过滤+分表),以便查询 - /// - /// - /// - /// - /// - /// - public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class { - var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); - foreach (var filter in filters) that.Where(filter.Value.Expression); - return that.AsTable(repos.AsTableSelectInternal); - } - - /// - /// 创建基于仓储功能的工作单元,务必使用 using 包含使用 - /// - /// - /// - public static IRepositoryUnitOfWork CreateUnitOfWork(this IFreeSql that) { - return new RepositoryUnitOfWork(that); - } -} \ No newline at end of file diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs deleted file mode 100644 index f965aaf6..00000000 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ /dev/null @@ -1,143 +0,0 @@ -using FreeSql.Extensions.EntityUtil; -using FreeSql.Internal.Model; -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 { - - internal IFreeSql _fsql; - internal RepositoryDbContext _db; - public IDataFilter DataFilter { get; } = new DataFilter(); - Func _asTableVal; - protected Func AsTable { - get => _asTableVal; - set { - _asTableVal = value; - AsTableSelect = value == null ? null : new Func((a, b) => a == EntityType ? value(b) : null); - } - } - internal Func AsTableInternal => AsTable; - protected Func AsTableSelect { get; private set; } - internal Func AsTableSelectInternal => AsTableSelect; - - protected BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) { - _fsql = fsql; - DataFilterUtil.SetRepositoryDataFilter(this, null); - DataFilter.Apply("", filter); - AsTable = asTable; - _db = new RepositoryDbContext(_fsql, this); - } - - ~BaseRepository() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - _db.Dispose(); - this.DataFilter.Dispose(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } - - public IUnitOfWork UnitOfWork { get; set; } - public Type EntityType => _db.DbSet._entityTypeInternal; - public IUpdate UpdateDiy => _db.DbSet.OrmUpdateInternal(null); - - public ISelect Select => _db.DbSet.OrmSelectInternal(null); - public ISelect Where(Expression> exp) => _db.DbSet.OrmSelectInternal(null).Where(exp); - public ISelect WhereIf(bool condition, Expression> exp) => _db.DbSet.OrmSelectInternal(null).WhereIf(condition, exp); - - public int Delete(Expression> predicate) => _db.DbSet.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows(); - public Task DeleteAsync(Expression> predicate) => _db.DbSet.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync(); - - public int Delete(TEntity entity) { - _db.DbSet.Remove(entity); - return _db.SaveChanges(); - } - public Task DeleteAsync(TEntity entity) { - _db.DbSet.Remove(entity); - return _db.SaveChangesAsync(); - } - public int Delete(IEnumerable entitys) { - _db.DbSet.RemoveRange(entitys); - return _db.SaveChanges(); - } - public Task DeleteAsync(IEnumerable entitys) { - _db.DbSet.RemoveRange(entitys); - return _db.SaveChangesAsync(); - } - - public virtual TEntity Insert(TEntity entity) { - _db.DbSet.Add(entity); - _db.SaveChanges(); - return entity; - } - async public virtual Task InsertAsync(TEntity entity) { - await _db.DbSet.AddAsync(entity); - _db.SaveChanges(); - return entity; - } - public virtual List Insert(IEnumerable entitys) { - _db.DbSet.AddRange(entitys); - _db.SaveChanges(); - return entitys.ToList(); - } - async public virtual Task> InsertAsync(IEnumerable entitys) { - await _db.DbSet.AddRangeAsync(entitys); - await _db.SaveChangesAsync(); - return entitys.ToList(); - } - - public int Update(TEntity entity) { - _db.DbSet.Update(entity); - return _db.SaveChanges(); - } - public Task UpdateAsync(TEntity entity) { - _db.DbSet.Update(entity); - return _db.SaveChangesAsync(); - } - public int Update(IEnumerable entitys) { - _db.DbSet.UpdateRange(entitys); - return _db.SaveChanges(); - } - public Task UpdateAsync(IEnumerable entitys) { - _db.DbSet.UpdateRange(entitys); - return _db.SaveChangesAsync(); - } - } - - 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) { - var stateKey = string.Concat(id); - if (_db.DbSet._statesInternal.ContainsKey(stateKey)) - _db.DbSet._statesInternal.Remove(stateKey); - return _db.DbSet.OrmDeleteInternal(id).ExecuteAffrows(); - } - public Task DeleteAsync(TKey id) { - var stateKey = string.Concat(id); - if (_db.DbSet._statesInternal.ContainsKey(stateKey)) - _db.DbSet._statesInternal.Remove(stateKey); - return _db.DbSet.OrmDeleteInternal(id).ExecuteAffrowsAsync(); - } - - public TEntity Find(TKey id) => _db.DbSet.OrmSelectInternal(id).ToOne(); - public Task FindAsync(TKey id) => _db.DbSet.OrmSelectInternal(id).ToOneAsync(); - - public TEntity Get(TKey id) => Find(id); - public Task GetAsync(TKey id) => FindAsync(id); - } -} diff --git a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs b/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs deleted file mode 100644 index 3079b308..00000000 --- a/FreeSql.DbContext/Repository/Repository/DefaultRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; - -namespace FreeSql { - public class DefaultRepository : - BaseRepository - where TEntity : class { - - public DefaultRepository(IFreeSql fsql) : base(fsql, null, null) { - - } - - public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter, null) { - } - } -} diff --git a/FreeSql.DbContext/Repository/Repository/GuidRepository.cs b/FreeSql.DbContext/Repository/Repository/GuidRepository.cs deleted file mode 100644 index 80a9ad7e..00000000 --- a/FreeSql.DbContext/Repository/Repository/GuidRepository.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; - -namespace FreeSql { - public class GuidRepository : - BaseRepository - where TEntity : class { - - public GuidRepository(IFreeSql fsql) : this(fsql, null, null) { - - } - public GuidRepository(IFreeSql fsql, Expression> filter, Func asTable) : base(fsql, filter, asTable) { - } - } -} diff --git a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs b/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs deleted file mode 100644 index 18b7db43..00000000 --- a/FreeSql.DbContext/Repository/Repository/IBasicRepository.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace FreeSql { - public interface IBasicRepository : IReadOnlyRepository - where TEntity : class { - TEntity Insert(TEntity entity); - List Insert(IEnumerable entitys); - Task InsertAsync(TEntity entity); - Task> InsertAsync(IEnumerable entitys); - - int Update(TEntity entity); - int Update(IEnumerable entitys); - Task UpdateAsync(TEntity entity); - Task UpdateAsync(IEnumerable entitys); - - IUpdate UpdateDiy { get; } - - int Delete(TEntity entity); - int Delete(IEnumerable entitys); - Task DeleteAsync(TEntity entity); - Task DeleteAsync(IEnumerable entitys); - } - - public interface IBasicRepository : IBasicRepository, IReadOnlyRepository - where TEntity : class { - int Delete(TKey id); - - Task DeleteAsync(TKey id); - } -} - diff --git a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs b/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs deleted file mode 100644 index 42284dc3..00000000 --- a/FreeSql.DbContext/Repository/Repository/IReadOnlyRepository.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql { - public interface IReadOnlyRepository : IRepository - where TEntity : class { - - IDataFilter DataFilter { get; } - - ISelect Select { get; } - - ISelect Where(Expression> exp); - ISelect WhereIf(bool condition, Expression> exp); - } - - public interface IReadOnlyRepository : IReadOnlyRepository - where TEntity : class { - TEntity Get(TKey id); - - Task GetAsync(TKey id); - - TEntity Find(TKey id); - - Task FindAsync(TKey id); - } -} diff --git a/FreeSql.DbContext/Repository/Repository/IRepository.cs b/FreeSql.DbContext/Repository/Repository/IRepository.cs deleted file mode 100644 index 631872a3..00000000 --- a/FreeSql.DbContext/Repository/Repository/IRepository.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace FreeSql { - - public interface IRepository : IDisposable { - Type EntityType { get; } - IUnitOfWork UnitOfWork { get; set; } - } - - public interface IRepository : IReadOnlyRepository, IBasicRepository - where TEntity : class { - int Delete(Expression> predicate); - - Task DeleteAsync(Expression> predicate); - } - - public interface IRepository : IRepository, IReadOnlyRepository, IBasicRepository - where TEntity : class { - } -} \ No newline at end of file diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs deleted file mode 100644 index 7a6d8c22..00000000 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Linq.Expressions; -using System.Text; - -namespace FreeSql { - public interface IUnitOfWork : IDisposable { - - DbTransaction GetOrBeginTransaction(bool isCreate = true); - - void Commit(); - - void Rollback(); - } -} diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs deleted file mode 100644 index 8f9df3b2..00000000 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ /dev/null @@ -1,73 +0,0 @@ -using SafeObjectPool; -using System; -using System.Collections.Generic; -using System.Data.Common; -using System.Linq.Expressions; -using System.Text; - -namespace FreeSql { - class UnitOfWork : IUnitOfWork { - - protected IFreeSql _fsql; - protected Object _conn; - protected DbTransaction _tran; - - public UnitOfWork(IFreeSql fsql) { - _fsql = fsql; - } - - void ReturnObject() { - _fsql.Ado.MasterPool.Return(_conn); - _tran = null; - _conn = null; - } - public DbTransaction GetOrBeginTransaction(bool isCreate = true) { - - if (_tran != null) return _tran; - if (isCreate == false) return null; - if (_conn != null) _fsql.Ado.MasterPool.Return(_conn); - - _conn = _fsql.Ado.MasterPool.Get(); - try { - _tran = _conn.Value.BeginTransaction(); - } catch { - ReturnObject(); - throw; - } - return _tran; - } - - public void Commit() { - if (_tran != null) { - try { - _tran.Commit(); - } finally { - ReturnObject(); - } - } - } - public void Rollback() { - if (_tran != null) { - try { - _tran.Rollback(); - } finally { - ReturnObject(); - } - } - } - ~UnitOfWork() { - this.Dispose(); - } - bool _isdisposed = false; - public void Dispose() { - if (_isdisposed) return; - try { - this.Rollback(); - } finally { - _isdisposed = true; - GC.SuppressFinalize(this); - } - } - - } -} diff --git a/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests.csproj index ad94b75b..30abb7c1 100644 --- a/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 6f7bc76a..287c2182 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -29,17 +29,6 @@ namespace FreeSql.Tests { ISelect select => g.mysql.Select(); - - class OrderContext : DbContext { - - public DbSet Orders { get; set; } - public DbSet OrderDetails { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder builder) { - builder.UseFreeSql(g.mysql); - } - } - class TestUser { [Column(IsIdentity = true)] public int stringid { get; set; } @@ -59,16 +48,7 @@ namespace FreeSql.Tests { .InnerJoin(a => a.LogOn.id == a.stringid).ToSql(); - using (var ctx = new OrderContext()) { - //ctx.Orders.OrmInsert(new Order { }).ExecuteAffrows(); - //ctx.Orders.OrmDelete.Where(a => a.Id > 0).ExecuteAffrows(); - - //ctx.OrderDetails.OrmSelect.Where(dt => dt.Order.Id == 10).ToList(); - - ctx.SaveChanges(); - } - - var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); + var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); var collSelect1 = g.mysql.Select().Where(a => diff --git a/FreeSql.sln b/FreeSql.sln index 15c97332..62ad8664 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -30,11 +30,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "domain_01", "Examples\domai EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "net461_console_01", "Examples\net461_console_01\net461_console_01.csproj", "{0637A778-338E-4096-B439-32B18306C75F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "orm_vs", "Examples\orm_vs\orm_vs.csproj", "{1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.DbContext", "FreeSql.DbContext\FreeSql.DbContext.csproj", "{E2D20A95-3045-49BD-973C-0CC6CEB957DB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dbcontext_01", "Examples\dbcontext_01\dbcontext_01.csproj", "{9ED752FF-F908-4611-827A-E99655607567}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "orm_vs", "Examples\orm_vs\orm_vs.csproj", "{1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -178,30 +174,6 @@ Global {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x64.Build.0 = Release|Any CPU {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x86.ActiveCfg = Release|Any CPU {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81}.Release|x86.Build.0 = Release|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x64.ActiveCfg = Debug|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x64.Build.0 = Debug|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x86.ActiveCfg = Debug|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Debug|x86.Build.0 = Debug|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|Any CPU.Build.0 = Release|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x64.ActiveCfg = Release|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x64.Build.0 = Release|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x86.ActiveCfg = Release|Any CPU - {E2D20A95-3045-49BD-973C-0CC6CEB957DB}.Release|x86.Build.0 = Release|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Debug|x64.ActiveCfg = Debug|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Debug|x64.Build.0 = Debug|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Debug|x86.ActiveCfg = Debug|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Debug|x86.Build.0 = Debug|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Release|Any CPU.Build.0 = Release|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Release|x64.ActiveCfg = Release|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Release|x64.Build.0 = Release|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Release|x86.ActiveCfg = Release|Any CPU - {9ED752FF-F908-4611-827A-E99655607567}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -213,7 +185,6 @@ Global {A23D0455-CA7B-442D-827E-C4C7E84F9084} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {0637A778-338E-4096-B439-32B18306C75F} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {1A5EC2EB-8C2B-4547-8AC6-EB5C0DE0CA81} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} - {9ED752FF-F908-4611-827A-E99655607567} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index 2c835770..8e8acde7 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -304,6 +304,37 @@ namespace FreeSql.Extensions.EntityUtil { func(item); } + static ConcurrentDictionary>> _dicClearEntityPrimaryValueWithIdentity = new ConcurrentDictionary>>(); + /// + /// 清除实体的主键值,将自增、Guid类型的主键值清除 + /// + /// + /// + /// + public static void ClearEntityPrimaryValueWithIdentity(this IFreeSql orm, TEntity item) { + var func = _dicClearEntityPrimaryValueWithIdentity.GetOrAdd(orm.Ado.DataType, dt => new ConcurrentDictionary>()).GetOrAdd(typeof(TEntity), t => { + var _table = orm.CodeFirst.GetTableByEntity(t); + var identitys = _table.Primarys.Where(a => a.Attribute.IsIdentity); + var parm1 = Expression.Parameter(typeof(object)); + var var1Parm = Expression.Variable(t); + var exps = new List(new Expression[] { + Expression.Assign(var1Parm, Expression.TypeAs(parm1, t)) + }); + foreach (var pk in _table.Primarys) { + if (pk.Attribute.IsIdentity) { + exps.Add( + Expression.Assign( + Expression.MakeMemberAccess(var1Parm, _table.Properties[pk.CsName]), + Expression.Default(pk.CsType) + ) + ); + } + } + return Expression.Lambda>(Expression.Block(new[] { var1Parm }, exps), new[] { parm1 }).Compile(); + }); + func(item); + } + static ConcurrentDictionary>> _dicCompareEntityValueReturnColumns = new ConcurrentDictionary>>(); /// /// 对比两个实体值,返回相同/或不相同的列名 diff --git a/FreeSql/FreeSql.MySql.csproj b/FreeSql/FreeSql.MySql.csproj deleted file mode 100644 index 0393902c..00000000 --- a/FreeSql/FreeSql.MySql.csproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - netstandard2.0 - 0.3.14 - true - YeXiangQin - 打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。 - https://github.com/2881099/FreeSql - FreeSql ORM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index fcbd8787..12b5e2bd 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.27 + 0.4.1 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.