private List <string> DeleteAbstract(object o, bool save) { object dbTrigger = null; GlobalConfiguration.Log?.Info("Delete", o); var type = o.GetType().GetActualType(); var props = DeepCloner.GetFastDeepClonerProperties(type); var table = type.TableName().GetName(_repository.DataBaseTypes); var primaryKey = o.GetType().GetPrimaryKey(); var primaryKeyValue = o.GetPrimaryKeyValue(); var objectRules = type.GetCustomAttribute <Rule>(); if (primaryKeyValue.ObjectIsNew()) { return(new List <string>()); } var sql = new List <string>() { "DELETE " + (_repository.DataBaseTypes == DataBaseTypes.Sqllight || _repository.DataBaseTypes == DataBaseTypes.PostgreSql ? "From " : "") + table + Querys.Where(_repository.DataBaseTypes).Column(primaryKey.GetPropertyName()).Equal(primaryKeyValue).Execute() }; if (objectRules != null && !CachedIDbRuleTrigger.ContainsKey(type)) { dbTrigger = objectRules.RuleType.CreateInstance(); CachedIDbRuleTrigger.Add(o.GetType(), dbTrigger); } else if (objectRules != null || CachedIDbRuleTrigger.ContainsKey(type)) { dbTrigger = CachedIDbRuleTrigger[type]; } try { _repository.CreateTransaction(); if (objectRules != null) { dbTrigger?.GetType().GetMethod("Delete").Invoke(dbTrigger, new List <object>() { _repository, o }.ToArray()); // Check the Rule before save } } catch { _repository.Rollback(); throw; } foreach (var prop in props.Where(x => x.CanRead && !x.IsInternalType && x.GetCustomAttribute <IndependentData>() == null && !x.ContainAttribute <JsonDocument>() && !x.ContainAttribute <XmlDocument>() && x.GetCustomAttribute <ExcludeFromAbstract>() == null)) { var value = prop.GetValue(o); if (value == null) { continue; } var subSql = new List <string>(); var propType = prop.PropertyType.GetActualType(); var insertBefore = props.Any(x => x.GetCustomAttribute <ForeignKey>()?.Type == propType); if (DeepCloner.GetFastDeepClonerProperties(propType).All(x => x.GetCustomAttribute <ForeignKey>()?.Type != type)) { if (!insertBefore) { continue; } } if (value is IList) { foreach (var item in value as IList) { subSql.AddRange(DeleteAbstract(item, false)); } } else { subSql.AddRange(DeleteAbstract(value, false)); } if (insertBefore) { sql.InsertRange(sql.Count - 1, subSql); } else { sql.AddRange(subSql); } } if (!save) { return(sql); } try { _repository.CreateTransaction(); var i = sql.Count - 1; var exceptionCount = 0; Exception firstChanceExcepion = null; while (sql.Count > 0 && exceptionCount <= 10) { try { if (i < 0) { i = sql.Count - 1; } var s = sql[i]; var cmd = _repository.GetSqlCommand(s); cmd.Command.ExecuteNonQuery(); sql.RemoveAt(i); i--; } catch (Exception e) { firstChanceExcepion = e; exceptionCount++; i--; } } if (exceptionCount >= 10) { throw firstChanceExcepion; } } catch { _repository.Rollback(); throw; } return(sql); }
private List <string> DeleteAbstract(object o, bool save) { GlobalConfiguration.Log?.Info("Delete", o); var type = o.GetType().GetActualType(); var props = DeepCloner.GetFastDeepClonerProperties(type); var table = "[" + (type.TableName()) + "]"; var primaryKey = o.GetType().GetPrimaryKey(); var primaryKeyValue = o.GetPrimaryKeyValue(); if (primaryKeyValue.ObjectIsNew()) { return(new List <string>()); } var sql = new List <string>() { "DELETE " + (_repository.DataBaseTypes == DataBaseTypes.Sqllight || _repository.DataBaseTypes == DataBaseTypes.PostgreSql ? "From " : "") + table + Querys.Where(_repository.DataBaseTypes).Column(primaryKey.GetPropertyName()).Equal(primaryKeyValue).Execute() }; foreach (var prop in props.Where(x => !x.IsInternalType && x.GetCustomAttribute <IndependentData>() == null && x.GetCustomAttribute <ExcludeFromAbstract>() == null)) { var value = prop.GetValue(o); if (value == null) { continue; } var subSql = new List <string>(); var propType = prop.PropertyType.GetActualType(); var insertBefore = props.Any(x => x.GetCustomAttribute <ForeignKey>()?.Type == propType); if (DeepCloner.GetFastDeepClonerProperties(propType).All(x => x.GetCustomAttribute <ForeignKey>()?.Type != type)) { if (!insertBefore) { continue; } } if (value is IList) { foreach (var item in value as IList) { subSql.AddRange(DeleteAbstract(item, false)); } } else { subSql.AddRange(DeleteAbstract(value, false)); } if (insertBefore) { sql.InsertRange(sql.Count - 1, subSql); } else { sql.AddRange(subSql); } } if (!save) { return(sql); } try { _repository.CreateTransaction(); var i = sql.Count - 1; var exceptionCount = 0; Exception firstChanceExcepion = null; while (sql.Count > 0 && exceptionCount <= 10) { try { if (i < 0) { i = sql.Count - 1; } var s = sql[i]; var cmd = _repository.GetSqlCommand(s); cmd.Command.ExecuteNonQuery(); sql.RemoveAt(i); i--; } catch (Exception e) { firstChanceExcepion = e; exceptionCount++; i--; } } if (exceptionCount >= 10) { throw firstChanceExcepion; } } catch { _repository.Rollback(); throw; } return(sql); }