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(DbContextStrings.CannotDelete_EntityHasNo_PrimaryKey(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { if (isThrow) { throw new Exception(DbContextStrings.CannotDelete_PrimaryKey_NotSet(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } //if (_states.TryGetValue(key, out var tryval) == false) { // if (isThrow) throw new Exception($"不可删除,数据未被跟踪,应该先查询:{_fsql.GetEntityString(_entityType, data)}"); // return false; //} return(true); }
protected override IUpdate <TEntity> OrmUpdate(IEnumerable <TEntity> entitys) { var update = base.OrmUpdate(entitys).AsTable(_repo.AsTableValueInternal); var filters = (_repo.DataFilter as DataFilter <TEntity>)._filters; foreach (var filter in filters.Where(a => a.Value.IsEnabled == true)) { if (entitys != null) { foreach (var entity in entitys) { if (filter.Value.ExpressionDelegate?.Invoke(entity) == false) { throw new Exception(DbContextStrings.UpdateError_Filter(filter.Key, filter.Value.Expression, _db.OrmOriginal.GetEntityString(_entityType, entity))); } } } update.Where(filter.Value.Expression); } var disableFilter = filters.Where(a => a.Value.IsEnabled == false).Select(a => a.Key).ToList(); disableFilter.AddRange((_repo.DataFilter as DataFilter <TEntity>)._filtersByOrm.Where(a => a.Value.IsEnabled == false).Select(a => a.Key)); if (disableFilter.Any()) { update.DisableGlobalFilter(disableFilter.ToArray()); } return(update); }
/// <summary> /// 比较实体,计算出值发生变化的属性,以及属性变化的前后值 /// </summary> /// <param name="newdata">最新的实体对象,它将与附加实体的状态对比</param> /// <returns>key: 属性名, value: [旧值, 新值]</returns> public Dictionary <string, object[]> CompareState(TEntity newdata) { if (newdata == null) { return(null); } if (_table.Primarys.Any() == false) { throw new Exception(DbContextStrings.Incomparable_EntityHasNo_PrimaryKey(_db.OrmOriginal.GetEntityString(_entityType, newdata))); } var key = _db.OrmOriginal.GetEntityKeyString(_entityType, newdata, false); if (string.IsNullOrEmpty(key)) { throw new Exception(DbContextStrings.Incomparable_PrimaryKey_NotSet(_db.OrmOriginal.GetEntityString(_entityType, newdata))); } if (_states.TryGetValue(key, out var oldState) == false || oldState == null) { return(_table.ColumnsByCs.ToDictionary(a => a.Key, a => new object[] { _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, newdata, a.Key), null })); } return(_db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, oldState.Value, newdata, false).ToDictionary(a => a, a => new object[] { _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, newdata, a), _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, oldState.Value, a) })); }
public void AttachRange(IEnumerable <TEntity> data) { if (data == null || data.Any() == false) { return; } if (_table.Primarys.Any() == false) { throw new Exception(DbContextStrings.CannotAttach_EntityHasNo_PrimaryKey(_db.OrmOriginal.GetEntityString(_entityType, data.First()))); } foreach (var item in data) { var key = _db.OrmOriginal.GetEntityKeyString(_entityType, item, false); if (string.IsNullOrEmpty(key)) { throw new Exception(DbContextStrings.CannotAttach_PrimaryKey_NotSet(_db.OrmOriginal.GetEntityString(_entityType, item))); } _states.AddOrUpdate(key, k => CreateEntityState(item), (k, ov) => { _db.OrmOriginal.MapEntityValue(_entityType, item, ov.Value); ov.Time = DateTime.Now; return(ov); }); } }
public UnitOfWorkManager(IFreeSql fsql) { if (fsql == null) { throw new ArgumentNullException(DbContextStrings.UnitOfWorkManager_Construction_CannotBeNull(nameof(UnitOfWorkManager), nameof(fsql))); } _ormScoped = DbContextScopedFreeSql.Create(fsql, null, () => this.Current); }
async Task <int> DbContextBatchUpdatePrivAsync(EntityState[] ups, bool isLiveUpdate, CancellationToken cancellationToken) { 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(DbContextStrings.SpecialError_UpdateFailedDataNotTracked(_db.OrmOriginal.GetEntityString(_entityType, uplst2.Value))); } var cuig1 = _db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, uplst1.Value, lstval1.Value, true); var cuig2 = uplst2 != null?_db.OrmOriginal.CompareEntityValueReturnColumns(_entityType, uplst2.Value, lstval2.Value, true) : null; List <EntityState> 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 update = this.OrmUpdate(null).SetSource(data.Select(a => a.Value)).IgnoreColumns(cuig); var affrows = await update.ExecuteAffrowsAsync(cancellationToken); _db._entityChangeReport.AddRange(data.Select(a => new DbContext.EntityChangeReport.ChangeInfo { EntityType = _entityType, Object = a.Value, BeforeObject = _states.TryGetValue(a.Key, out var beforeVal) ? CreateEntityState(beforeVal.Value).Value : null, Type = DbContext.EntityChangeType.Update }));
protected override IInsert <TEntity> OrmInsert(IEnumerable <TEntity> entitys) { var insert = base.OrmInsert(entitys).AsTable(_repo.AsTableValueInternal); var filters = (_repo.DataFilter as DataFilter <TEntity>)._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(DbContextStrings.InsertError_Filter(filter.Key, filter.Value.Expression, _db.OrmOriginal.GetEntityString(_entityType, entity))); } } } } return(insert); }
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(DbContextStrings.CannotUpdate_EntityHasNo_PrimaryKey(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } FreeSql.Internal.CommonProvider.UpdateProvider <TEntity> .AuditDataValue(this, data, _db.OrmOriginal, _table, null); var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, false); if (string.IsNullOrEmpty(key)) { if (isThrow) { throw new Exception(DbContextStrings.CannotUpdate_PrimaryKey_NotSet(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } if (_states.TryGetValue(key, out var tryval) == false) { if (isThrow) { throw new Exception(DbContextStrings.CannotUpdate_DataShouldQueryOrAttach(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } return(true); }
async public Task SaveManyAsync(TEntity item, string propertyName, CancellationToken cancellationToken = default) { if (item == null) { return; } if (string.IsNullOrEmpty(propertyName)) { return; } if (_table.Properties.TryGetValue(propertyName, out var prop) == false) { throw new KeyNotFoundException(DbContextStrings.NotFound_Property(_table.Type.FullName, propertyName)); } if (_table.ColumnsByCsIgnore.ContainsKey(propertyName)) { throw new ArgumentException(DbContextStrings.TypeHasSetProperty_IgnoreAttribute(_table.Type.FullName, propertyName)); } var tref = _table.GetTableRef(propertyName, true); if (tref == null) { return; } switch (tref.RefType) { case Internal.Model.TableRefType.OneToOne: case Internal.Model.TableRefType.ManyToOne: throw new ArgumentException(DbContextStrings.PropertyOfType_IsNot_OneToManyOrManyToMany(_table.Type.FullName, propertyName)); } await DbContextFlushCommandAsync(cancellationToken); var oldEnable = _db.Options.EnableCascadeSave; _db.Options.EnableCascadeSave = false; try { await AddOrUpdateNavigateAsync(item, false, propertyName, cancellationToken); if (tref.RefType == Internal.Model.TableRefType.OneToMany) { await DbContextFlushCommandAsync(cancellationToken); //删除没有保存的数据,求出主体的条件 var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); Expression whereParentExp = null; for (var colidx = 0; colidx < tref.Columns.Count; colidx++) { var whereExp = Expression.Equal( Expression.MakeMemberAccess(Expression.Convert(deleteWhereParentParam, tref.RefEntityType), tref.RefColumns[colidx].Table.Properties[tref.RefColumns[colidx].CsName]), Expression.Constant( FreeSql.Internal.Utils.GetDataReaderValue( tref.Columns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName)), tref.RefColumns[colidx].CsType) ); if (whereParentExp == null) { whereParentExp = whereExp; } else { whereParentExp = Expression.AndAlso(whereParentExp, whereExp); } } var propValEach = GetItemValue(item, prop) as IEnumerable; var subDelete = _db.OrmOriginal.Delete <object>().AsType(tref.RefEntityType) .WithTransaction(_uow?.GetOrBeginTransaction()) .Where(Expression.Lambda <Func <object, bool> >(whereParentExp, deleteWhereParentParam)); foreach (var propValItem in propValEach) { subDelete.WhereDynamic(propValEach, true); break; } await subDelete.ExecuteAffrowsAsync(cancellationToken); } } finally { _db.Options.EnableCascadeSave = oldEnable; } }
async public Task AddRangeAsync(IEnumerable <TEntity> data, CancellationToken cancellationToken = default) { if (CanAdd(data, true) == false) { return; } if (data.ElementAtOrDefault(1) == default(TEntity)) { await AddAsync(data.First(), cancellationToken); return; } if (_tableReturnColumns.Length > 0) { //有自增,马上执行 switch (_db.OrmOriginal.Ado.DataType) { case DataType.SqlServer: case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: await DbContextFlushCommandAsync(cancellationToken); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(cancellationToken); if (rets.Count != data.Count()) { throw new Exception(DbContextStrings.SpecialError_BatchAdditionFailed(_db.OrmOriginal.Ado.DataType)); } _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); var idx = 0; foreach (var s in data) { _db.OrmOriginal.MapEntityValue(_entityType, rets[idx++], s); } IncrAffrows(rets.Count); AttachRange(rets); if (_db.Options.EnableCascadeSave) { foreach (var item in data) { await AddOrUpdateNavigateAsync(item, true, null, cancellationToken); } } return; default: if (_tableIdentitys.Length == 1) { foreach (var s in data) { await AddPrivAsync(s, false, cancellationToken); } return; } break; } } //进入队列,等待 SaveChanges 时执行 foreach (var item in data) { EnqueueToDbContext(DbContext.EntityChangeType.Insert, CreateEntityState(item)); } AttachRange(data); if (_db.Options.EnableCascadeSave) { foreach (var item in data) { await AddOrUpdateNavigateAsync(item, true, null, cancellationToken); } } }
bool CanAdd(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(DbContextStrings.CannotAdd_EntityHasNo_PrimaryKey(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } FreeSql.Internal.CommonProvider.InsertProvider <TEntity> .AuditDataValue(this, data, _db.OrmOriginal, _table, null); var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, true); if (string.IsNullOrEmpty(key)) { switch (_db.OrmOriginal.Ado.DataType) { case DataType.SqlServer: case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: case DataType.KingbaseES: case DataType.OdbcKingbaseES: case DataType.ShenTong: case DataType.ClickHouse: return(true); default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { return(true); } if (isThrow) { throw new Exception(DbContextStrings.CannotAdd_PrimaryKey_NotSet(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } } else { if (_states.ContainsKey(key)) { if (isThrow) { throw new Exception(DbContextStrings.CannotAdd_AlreadyExistsInStateManagement(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } if (_db.OrmOriginal.Ado.DataType == DataType.ClickHouse) { return(true); } var idval = _db.OrmOriginal.GetEntityIdentityValueWithPrimary(_entityType, data); if (idval > 0) { if (isThrow) { throw new Exception(DbContextStrings.CannotAdd_SelfIncreasingHasValue(_db.OrmOriginal.GetEntityString(_entityType, data))); } return(false); } } return(true); }