internal static string CreateTable(ICustomRepository repository, Type tableType, List <Type> createdTables = null, bool commit = true, bool force = false, Dictionary <string, Tuple <string, ForeignKey> > keys = null) { if (createdTables == null) { createdTables = new List <Type>(); } var tableData = ObjectColumns(repository, tableType); if (createdTables.Any(x => x == tableType)) { return(null); } if (!force && tableData.Rows.Any()) { return(null); } repository.CreateTransaction(); RemoveTable(repository, tableType); createdTables.Add(tableType); if (keys == null) { keys = new Dictionary <string, Tuple <string, ForeignKey> >(); } List <string> sqlList = new List <string>(); try { var isSqllite = repository.GetDataBaseType() == DataBaseTypes.Sqllight; var props = DeepCloner.GetFastDeepClonerProperties(tableType); var tableName = tableType.GetCustomAttribute <Table>()?.Name ?? tableType.Name; var sql = new StringBuilder("CREATE TABLE " + (!isSqllite ? "[dbo]." : "") + "[" + tableName + "]("); var isPrimaryKey = ""; foreach (var prop in props.Where(x => x.PropertyType.GetDbTypeByType() != null && !x.ContainAttribute <ExcludeFromAbstract>() && x.IsInternalType).GroupBy(x => x.Name).Select(x => x.First())) { isPrimaryKey = prop.ContainAttribute <PrimaryKey>() ? prop.GetPropertyName() : isPrimaryKey; var forgenKey = prop.GetCustomAttribute <ForeignKey>(); var dbType = prop.PropertyType.GetDbTypeByType(); var propName = prop.GetPropertyName(); sql.Append(propName + " "); if (!prop.ContainAttribute <PrimaryKey>() || !isSqllite) { sql.Append(dbType + " "); } if (forgenKey != null) { sqlList.Add(CreateTable(repository, forgenKey.Type, createdTables, false, force, keys)); } if (prop.ContainAttribute <PrimaryKey>()) { if (!isSqllite) { sql.Append("IDENTITY(1,1) NOT NULL,"); } else { sql.Append(" Integer PRIMARY KEY AUTOINCREMENT,"); } continue; } if (forgenKey != null) { keys.Add(propName, new Tuple <string, ForeignKey>(tableName, forgenKey)); } sql.Append(Nullable.GetUnderlyingType(prop.PropertyType) != null ? " NULL," : " NOT NULL,"); } if (keys.Any() && isSqllite) { foreach (var key in keys) { var type = key.Value.Item2.Type.GetActualType(); var keyPrimary = type.GetPrimaryKey().GetPropertyName(); var tb = type.GetCustomAttribute <Table>().Name ?? type.Name; sql.Append("FOREIGN KEY(" + key.Key + ") REFERENCES " + tb + "(" + keyPrimary + "),"); } keys.Clear(); } if (!string.IsNullOrEmpty(isPrimaryKey) && !isSqllite) { sql.Append(" CONSTRAINT [PK_" + tableName + "] PRIMARY KEY CLUSTERED"); sql.Append(" ([" + isPrimaryKey + "] ASC"); sql.Append(")"); sql.Append( "WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]"); sql.Append(") ON [PRIMARY]"); } else { if (isSqllite) { sql = new StringBuilder(sql.ToString().TrimEnd(',')); } sql.Append(")"); } if (!commit) { return(sql.ToString()); } foreach (var prop in props.Where(x => !x.IsInternalType && !x.ContainAttribute <ExcludeFromAbstract>()).GroupBy(x => x.Name).Select(x => x.First())) { var type = prop.PropertyType.GetActualType(); sqlList.Add(CreateTable(repository, type, createdTables, false, force, keys)); } sqlList.Insert(0, sql.ToString()); sqlList.RemoveAll(x => string.IsNullOrEmpty(x)); var c = sqlList.Count; while (c > 0) { for (var i = sqlList.Count - 1; i >= 0; i--) { try { var s = sqlList[i]; var cmd = repository.GetSqlCommand(s); repository.ExecuteNonQuery(cmd); c--; } catch (Exception ex) { var test = ex; } } } sql = new StringBuilder(); if (keys.Any() && !isSqllite) { foreach (var key in keys) { var type = key.Value.Item2.Type.GetActualType(); var keyPrimary = type.GetPrimaryKey().GetPropertyName(); var tb = type.GetCustomAttribute <Table>()?.Name ?? type.Name; sql.Append("ALTER TABLE [" + key.Value.Item1 + "] ADD FOREIGN KEY (" + key.Key + ") REFERENCES [" + tb + "](" + keyPrimary + ");"); } var s = sql.ToString(); var cmd = repository.GetSqlCommand(s); repository.ExecuteNonQuery(cmd); } repository.Commit(); } catch (Exception ex) { repository.Rollback(); throw ex; } return(string.Empty); }
public CodeToDataBaseMergeCollection GetDatabase_Diff(Type tableType, CodeToDataBaseMergeCollection str = null, List <Type> createdTables = null) { str = str ?? new CodeToDataBaseMergeCollection(_repository); if (tableType.GetCustomAttribute <ExcludeFromAbstract>() != null || _alreadyControlled.Any(x => x == tableType)) { return(str); } _repository.CreateSchema(tableType); tableType = tableType.GetActualType(); _alreadyControlled.Add(tableType); createdTables = createdTables ?? new List <Type>(); if (createdTables.Any(x => x == tableType) || tableType.GetPrimaryKey() == null) { return(str); } if (CodeToDataBaseMergeCollection.ExecutedData.ContainsKey(tableType.FullName + _repository.DataBaseTypes.ToString())) { return(str); } createdTables.Add(tableType); var table = _repository.GetColumnSchema(tableType); var tableName = tableType.TableName(); var props = DeepCloner.GetFastDeepClonerProperties(tableType).Where(x => x.CanRead && !x.ContainAttribute <ExcludeFromAbstract>()); var codeToDataBaseMerge = new CodeToDataBaseMerge() { Object_Type = tableType }; var isPrimaryKey = ""; if (!IsValidName(tableName.Name)) { throw new EntityException(tableName.Name + " is not a valid Name for the current provider " + _repository.DataBaseTypes); } if (!table.Values.Any()) { codeToDataBaseMerge.Sql = new StringBuilder($"CREATE TABLE {tableName.GetName(_repository.DataBaseTypes)} ("); foreach (var prop in props.Where(x => (x.GetDbTypeByType(_repository.DataBaseTypes) != null || !x.IsInternalType || x.ContainAttribute <JsonDocument>() || x.ContainAttribute <XmlDocument>()) && !x.ContainAttribute <ExcludeFromAbstract>()).GroupBy(x => x.Name).Select(x => x.First()) .OrderBy(x => x.ContainAttribute <PrimaryKey>() ? null : x.Name)) { if (!prop.IsInternalType && !prop.ContainAttribute <JsonDocument>() && !prop.ContainAttribute <XmlDocument>()) { if (!str.Any(x => x.Object_Type == prop.PropertyType.GetActualType()) && createdTables.All(x => x != prop.PropertyType.GetActualType())) { GetDatabase_Diff(prop.PropertyType, str, createdTables); } continue; } isPrimaryKey = prop.ContainAttribute <PrimaryKey>() ? prop.GetPropertyName() : isPrimaryKey; var foreignKey = prop.GetCustomAttribute <ForeignKey>(); var dbType = prop.GetDbTypeByType(_repository.DataBaseTypes); var propName = string.Format("[{0}]", prop.GetPropertyName()); codeToDataBaseMerge.Sql.Append(propName + " "); if (!IsValidName(prop.GetPropertyName())) { throw new Exception(prop.GetPropertyName() + " is not a valid Name for the current provider " + _repository.DataBaseTypes); } if (!prop.ContainAttribute <PrimaryKey>() || _repository.DataBaseTypes == DataBaseTypes.Mssql) { codeToDataBaseMerge.Sql.Append(dbType + " "); } if (foreignKey != null && createdTables.All(x => x != foreignKey.Type)) { GetDatabase_Diff(foreignKey.Type, str, createdTables); } if (prop.ContainAttribute <PrimaryKey>()) { if (prop.PropertyType.IsNumeric() && prop.GetCustomAttribute <PrimaryKey>().AutoGenerate) { codeToDataBaseMerge.Sql.Append(_repository.DataBaseTypes == DataBaseTypes.Mssql ? "IDENTITY(1,1) NOT NULL," : (_repository.DataBaseTypes == DataBaseTypes.Sqllight ? " Integer PRIMARY KEY AUTOINCREMENT," : " BIGSERIAL PRIMARY KEY,")); } else { codeToDataBaseMerge.Sql.Append(_repository.DataBaseTypes == DataBaseTypes.Mssql ? "NOT NULL," : " " + dbType + " PRIMARY KEY,"); } continue; } if (foreignKey != null) { var key = propName + "-" + tableName.GetName(_repository.DataBaseTypes); if (!str.Keys.ContainsKey(key)) { str.Keys.Add(key, new Tuple <string, ForeignKey>(tableName.GetName(_repository.DataBaseTypes), foreignKey)); } } codeToDataBaseMerge.Sql.Append((Nullable.GetUnderlyingType(prop.PropertyType) != null || prop.PropertyType == typeof(string)) && !prop.ContainAttribute <NotNullable>() ? " NULL," : " NOT NULL,"); } if (str.Keys.Any() && _repository.DataBaseTypes == DataBaseTypes.Sqllight) { while (str.Keys.Any(x => x.Value.Item1 == tableName.Name)) { var key = str.Keys.FirstOrDefault(x => x.Value.Item1 == tableName.Name); var type = key.Value.Item2.Type.GetActualType(); var keyPrimary = type.GetPrimaryKey().GetPropertyName(); var tb = type.TableName(); codeToDataBaseMerge.Sql.Append("FOREIGN KEY(" + key.Key.Split('-')[0] + ") REFERENCES " + tb.GetName(_repository.DataBaseTypes) + "(" + keyPrimary + "),"); str.Keys.Remove(key.Key); } } if (!string.IsNullOrEmpty(isPrimaryKey) && _repository.DataBaseTypes == DataBaseTypes.Mssql) { codeToDataBaseMerge.Sql.Append(" CONSTRAINT [PK_" + tableName.Name + "] PRIMARY KEY CLUSTERED"); codeToDataBaseMerge.Sql.Append(" ([" + isPrimaryKey + "] ASC"); codeToDataBaseMerge.Sql.Append(")"); codeToDataBaseMerge.Sql.Append("WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]"); codeToDataBaseMerge.Sql.Append(") ON [PRIMARY]"); } else { if (_repository.DataBaseTypes == DataBaseTypes.Sqllight) { codeToDataBaseMerge.Sql = new StringBuilder(codeToDataBaseMerge.Sql.ToString().TrimEnd(',')); } codeToDataBaseMerge.Sql.Append(")"); } str.Add(codeToDataBaseMerge); } else { foreach (var prop in props.Where(x => (x.GetDbTypeByType(_repository.DataBaseTypes) != null || !x.IsInternalType) && !x.ContainAttribute <ExcludeFromAbstract>()).GroupBy(x => x.Name).Select(x => x.First()) .OrderBy(x => x.ContainAttribute <PrimaryKey>() ? null : x.Name)) { if (prop.ContainAttribute <ForeignKey>()) { GetDatabase_Diff(prop.GetCustomAttribute <ForeignKey>().Type, str, createdTables); } var propType = prop.PropertyType; if (prop.ContainAttribute <Stringify>() || prop.ContainAttribute <DataEncode>() || prop.ContainAttribute <ToBase64String>() || prop.ContainAttribute <JsonDocument>() || prop.ContainAttribute <XmlDocument>()) { propType = typeof(string); } var modify = prop.IsInternalType || prop.ContainAttribute <JsonDocument>() || prop.ContainAttribute <XmlDocument>() ? (_repository.DataBaseTypes == DataBaseTypes.PostgreSql ? table.Get(prop.GetPropertyName().ToLower()) : table.Get(prop.GetPropertyName())) : null; if (modify != null) { if (_repository.DataBaseTypes != DataBaseTypes.Sqllight && !(prop.GetDbTypeListByType(_repository.DataBaseTypes).Any(x => x.ToLower().Contains(modify.DataType.ToLower()))) && _repository.DataBaseTypes != DataBaseTypes.PostgreSql) { var constraine = Properties.Resources.DropContraine .Replace("@tb", $"'{tableName.Name}'").Replace("@col", $"'{prop.GetPropertyName()}'") .Replace("@schema", $"'{tableName.Schema ?? ""}'") .Replace("@TableName", "@" + counter++) .Replace("@ColumnName", "@" + counter++) .Replace("@fullName", "@" + counter++) .Replace("@DROP_COMMAND", "@" + counter++) .Replace("@FOREIGN_KEY_NAME", "@" + counter++); codeToDataBaseMerge.Sql.Append(constraine); codeToDataBaseMerge.Sql.Append($"\nALTER TABLE {tableName.GetName(_repository.DataBaseTypes)} ALTER COLUMN [{prop.GetPropertyName()}] {prop.GetDbTypeByType(_repository.DataBaseTypes)} {((Nullable.GetUnderlyingType(propType) != null || propType == typeof(string)) && !prop.ContainAttribute<NotNullable>() ? " NULL" : " NOT NULL")}"); } else { if (!(prop.GetDbTypeListByType(_repository.DataBaseTypes).Any(x => x.ToLower().Contains(modify.DataType.ToLower()))) && _repository.DataBaseTypes == DataBaseTypes.PostgreSql) { codeToDataBaseMerge.Sql.Append($"\nALTER TABLE {tableName.GetName(_repository.DataBaseTypes)} ALTER COLUMN [{prop.GetPropertyName()}] TYPE {prop.GetDbTypeByType(_repository.DataBaseTypes)}, ALTER COLUMN [{prop.GetPropertyName()}] SET DEFAULT {Querys.GetValueByTypeSTRING(MethodHelper.ConvertValue(null, propType), _repository.DataBaseTypes)};"); } } } else if (!prop.IsInternalType && !prop.ContainAttribute <JsonDocument>() && !prop.ContainAttribute <XmlDocument>()) { GetDatabase_Diff(prop.PropertyType, str, createdTables); } else { codeToDataBaseMerge.Sql.Append(string.Format("\nALTER TABLE {0} ADD " + (_repository.DataBaseTypes == DataBaseTypes.PostgreSql ? "COLUMN" : "") + " [{1}] {2} {3} DEFAULT {4};", tableName.GetName(_repository.DataBaseTypes), prop.GetPropertyName(), prop.GetDbTypeByType(_repository.DataBaseTypes), (Nullable.GetUnderlyingType(propType) != null || propType == typeof(string)) && !prop.ContainAttribute <NotNullable>() ? " NULL" : " NOT NULL", Querys.GetValueByTypeSTRING(MethodHelper.ConvertValue(null, propType), _repository.DataBaseTypes))); } } } var colRemove = new CodeToDataBaseMerge() { Object_Type = tableType }; // Now lets clean the table and remove unused columns foreach (var col in table.Values.Where(x => !props.Any(a => string.Equals(x.ColumnName, a.GetPropertyName(), StringComparison.CurrentCultureIgnoreCase) && (a.GetDbTypeByType(_repository.DataBaseTypes) != null || (!a.IsInternalType || a.ContainAttribute <JsonDocument>() || a.ContainAttribute <XmlDocument>())) && !a.ContainAttribute <ExcludeFromAbstract>()))) { if (_repository.DataBaseTypes != DataBaseTypes.Sqllight) { if (_repository.DataBaseTypes == DataBaseTypes.Mssql) { var constraine = Properties.Resources.DropContraine .Replace("@tb", $"'{tableName.Name}'") .Replace("@col", $"'{col.ColumnName}'") .Replace("@schema", $"'{tableName.Schema ?? ""}'") .Replace("@TableName", "@" + counter++) .Replace("@ColumnName", "@" + counter++) .Replace("@fullName", "@" + counter++) .Replace("@DROP_COMMAND", "@" + counter++) .Replace("@FOREIGN_KEY_NAME", "@" + counter++); colRemove.Sql.Append(constraine); } colRemove.Sql.Append(string.Format("\nALTER TABLE {0} DROP COLUMN IF EXISTS [{1}];", tableName.GetName(_repository.DataBaseTypes), col.ColumnName)); } else { colRemove.Sql.Append(string.Format("DROP TABLE IF exists [{0}_temp];\nCREATE TABLE [{0}_temp] AS SELECT {1} FROM [{0}];", tableName.Name, string.Join(",", table.Values.ToList().FindAll(x => props.Any(a => string.Equals(x.ColumnName, a.GetPropertyName(), StringComparison.CurrentCultureIgnoreCase) && (a.GetDbTypeByType(_repository.DataBaseTypes) != null || !a.IsInternalType) && !a.ContainAttribute <ExcludeFromAbstract>())).Select(x => x.ColumnName)))); colRemove.Sql.Append(string.Format("DROP TABLE [{0}];\n", tableName.Name)); colRemove.Sql.Append(string.Format("ALTER TABLE [{0}_temp] RENAME TO [{0}]; ", tableName.Name)); } colRemove.DataLoss = true; } str.Add(colRemove); foreach (var prop in props.Where(x => !x.IsInternalType && !x.ContainAttribute <JsonDocument>() && !x.ContainAttribute <XmlDocument>() && !x.ContainAttribute <XmlDocument>() && !x.ContainAttribute <ExcludeFromAbstract>()).GroupBy(x => x.Name).Select(x => x.First())) { var type = prop.PropertyType.GetActualType(); if (type.GetPrimaryKey() != null) { GetDatabase_Diff(type, str, createdTables); } } str.Add(codeToDataBaseMerge); return(str); }
internal static IList DataReaderConverter(Transaction.Transaction repository, IDataReader reader, DbCommandExtended command, Type type) { var tType = type.GetActualType(); var attachable = tType.GetPrimaryKey() != null; var baseListType = typeof(List <>); var listType = baseListType.MakeGenericType(tType); var iList = DeepCloner.CreateInstance(listType) as IList; var props = DeepCloner.GetFastDeepClonerProperties(tType); try { var colNames = new Custom_ValueType <int, string>(); var pp = new Custom_ValueType <int, FastDeepCloner.IFastDeepClonerProperty>(); while (reader.Read()) { object item = null; object clItem = null; item = DeepCloner.CreateInstance(tType); clItem = attachable ? DeepCloner.CreateInstance(tType) : null; var col = 0; while (col < reader.FieldCount) { string columnName; if (colNames.ContainsKey(col)) { columnName = colNames[col]; } else { columnName = reader.GetName(col); colNames.TryAdd(col, columnName); } var value = reader[columnName]; IFastDeepClonerProperty prop; if (!pp.ContainsKey(col)) { prop = DeepCloner.GetProperty(tType, columnName); if (prop == null) { prop = props.FirstOrDefault(x => string.Equals(x.GetPropertyName(), columnName, StringComparison.CurrentCultureIgnoreCase) || x.GetPropertyName().ToLower() == columnName); } pp.TryAdd(col, prop); } else { prop = pp[col]; } if (prop != null && value != DBNull.Value && value != null && prop.CanRead) { if (value as byte[] != null && prop.PropertyType.FullName.Contains("Guid")) { value = new Guid(value as byte[]); } var dataEncode = prop.GetCustomAttribute <DataEncode>(); if (prop.ContainAttribute <ToBase64String>()) { if (value.ConvertValue <string>().IsBase64String()) { value = MethodHelper.DecodeStringFromBase64(value.ConvertValue <string>()); } else { value = MethodHelper.ConvertValue(value, prop.PropertyType); } } else if (dataEncode != null) { value = new DataCipher(dataEncode.Key, dataEncode.KeySize).Decrypt(value.ConvertValue <string>()); } else if (prop.ContainAttribute <JsonDocument>()) { value = value?.ToString().FromJson(prop.PropertyType); } else if (prop.ContainAttribute <XmlDocument>()) { value = value?.ToString().FromXml(); } else { value = MethodHelper.ConvertValue(value, prop.PropertyType); } prop.SetValue(item, value); if (attachable) { prop.SetValue(clItem, value); } } col++; } if (clItem != null && !(repository?.IsAttached(clItem) ?? true)) { repository?.AttachNew(clItem); } iList.Add(item); } } catch (Exception e) { throw e; } finally { reader.Close(); reader.Dispose(); if (repository.OpenedDataReaders.ContainsKey(reader)) { repository.OpenedDataReaders.Remove(reader); } } return(iList); }
public void ProxyTest() { var pUser = DeepCloner.CreateProxyInstance <User>(); pUser.Name = "testo"; }
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); }
public void RemoveTable(Type tableType, List <Type> tableRemoved = null, bool remove = true) { if (tableRemoved == null) { tableRemoved = new List <Type>(); } if (tableRemoved.Any(x => x == tableType)) { return; } GlobalConfiguration.Log?.Info("Removig", tableType); tableRemoved.Insert(0, tableType); var props = DeepCloner.GetFastDeepClonerProperties(tableType); foreach (var prop in props.Where(x => (!x.IsInternalType || x.ContainAttribute <ForeignKey>()) && !x.ContainAttribute <ExcludeFromAbstract>())) { var key = prop.GetCustomAttribute <ForeignKey>(); if (key != null && tableRemoved.Any(x => x == key.Type)) { continue; } if (key != null) { RemoveTable(key.Type, tableRemoved, false); } else { RemoveTable(prop.PropertyType.GetActualType(), tableRemoved, false); } } if (!remove) { return; } var tableData = ObjectColumns(tableType); if (!tableData.Rows.Any()) { return; } var c = tableRemoved.Count; _repository.CreateTransaction(); while (c > 0) { for (var i = tableRemoved.Count - 1; i >= 0; i--) { try { var tType = tableRemoved[i]; if (ObjectColumns(tType).Rows.Any()) { CachedObjectColumn.Remove(tType.FullName + _repository.DataBaseTypes.ToString()); if (Extension.CachedDataRecord.ContainsKey(tType)) { Extension.CachedDataRecord.Remove(tType); } var tableName = tType.TableName(); _repository.ExecuteNonQuery(_repository.GetSqlCommand("DELETE FROM [" + tableName + "];")); var cmd = _repository.GetSqlCommand("DROP TABLE [" + tableName + "];"); _repository.ExecuteNonQuery(cmd); CachedObjectColumn.Remove(tType.FullName + _repository.DataBaseTypes.ToString()); } c--; } catch (NpgsqlException ex) { _repository.Renew(); } catch { // Ignore } } } }
internal override InterpolatedQuery Clone() { return(new LanguageInterpolatedQuery(Query, Parameters.Select(x => DeepCloner.DeepClone(x)).ToArray(), UsedTypes)); }
private void ApplyTo(T2 item, object obj) { TLCGenTemplateModel <T2> template = SelectedTemplate as TLCGenTemplateModel <T2>; var tempitem = template.GetItems()?.FirstOrDefault(); // originalName: name of item if no argument was passed; otherwise, the argument // this allows for renaming items in lists belonging to an item var orignalName = obj == null ? (item as IHaveName)?.Naam : obj as string; // originalItemName: store the item name if an argument was passed // this allows to rename potential items in lists of this item while // maintaining the name of the item itself var orignalItemName = obj != null ? (item as IHaveName)?.Naam : null; if (tempitem != null && orignalName != null) { var cloneditem = DeepCloner.DeepClone((T2)tempitem); var props = typeof(T2).GetProperties().Where(x => x.CanWrite && x.CanRead).ToList(); foreach (var prop in props) { var templateApplicableAttr = prop.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(NoTemplateApplicableAttribute)); if (templateApplicableAttr != null) { continue; } object valueOriginal = prop.GetValue(item); object valueCloned = prop.GetValue(cloneditem); if (prop.PropertyType.IsValueType || prop.PropertyType == typeof(string)) { prop.SetValue(item, valueCloned); } else if (valueOriginal is IList elems) { if (elems.Count == 0 || !(elems[0] is IHaveName)) { elems.Clear(); } else { var l = new List <IHaveName>(); foreach (IHaveName i in elems) { l.Add(i); } foreach (var i in l) { Integrity.TLCGenControllerModifier.Default.RemoveModelItemFromController(i.Naam); } } var clonedItems = (IList)valueCloned; foreach (var e in clonedItems) { elems.Add(e); } } } if (_replaceNameOnApply) { ModelStringSetter.ReplaceStringInModel(item, template.Replace, orignalName); } if (orignalItemName != null) { ((IHaveName)item).Naam = orignalItemName; } } }
private void ImportControllerCommand_Executed(object obj) { if (obj == null) { throw new NullReferenceException(); } if (!(obj is ITLCGenImporter imp)) { throw new InvalidCastException(); } // Import into existing controller if (TLCGenControllerDataProvider.Default.CheckChanged()) { return; } if (imp.ImportsIntoExisting) { // Request to process all synchronisation data from matrix to model Messenger.Default.Send(new ProcessSynchronisationsRequest()); // Check data integrity var s1 = TLCGenIntegrityChecker.IsConflictMatrixOK(ControllerVM.Controller); if (s1 != null) { TLCGenDialogProvider.Default.ShowMessageBox("Kan niet importeren:\n\n" + s1, "Error bij importeren: fout in regeling"); return; } // Import to clone of original (so we can discard if wrong) var c1 = DeepCloner.DeepClone(ControllerVM.Controller); var c2 = imp.ImportController(c1); // Do nothing if the importer returned nothing if (c2 == null) { TLCGenDialogProvider.Default.ShowMessageBox("Importeren is afgebroken door de gebruiker", "Importeren afgebroken"); return; } // Check data integrity c2.Data.GarantieOntruimingsTijden = false; s1 = TLCGenIntegrityChecker.IsConflictMatrixOK(c2); if (s1 != null) { TLCGenDialogProvider.Default.ShowMessageBox("Fout bij importeren:\n\n" + s1, "Error bij importeren: fout in data"); return; } if (c1.Data.GarantieOntruimingsTijden) { TLCGenDialogProvider.Default.ShowMessageBox("De bestaande regeling had garantie ontruimingstijden.\nDeze zijn nu uitgeschakeld.", "Garantie ontruimingstijden uitrgeschakeld"); } SetController(c2); ControllerVM.ReloadController(); GuiActionsManager.SetStatusBarMessage( DateTime.Now.ToLongTimeString() + " - Data in regeling " + TLCGenControllerDataProvider.Default.Controller.Data.Naam + " geïmporteerd"); } // Import as new controller else { var c1 = imp.ImportController(); // Do nothing if the importer returned nothing if (c1 == null) { return; } // Check data integrity var s1 = TLCGenIntegrityChecker.IsConflictMatrixOK(c1); if (s1 != null) { TLCGenDialogProvider.Default.ShowMessageBox("Fout bij importeren:\n\n" + s1, "Error bij importeren: fout in data"); return; } TLCGenControllerDataProvider.Default.CloseController(); DefaultsProvider.Default.SetDefaultsOnModel(c1.Data); DefaultsProvider.Default.SetDefaultsOnModel(c1.OVData); SetController(c1); ControllerVM.ReloadController(); GuiActionsManager.SetStatusBarMessage( DateTime.Now.ToLongTimeString() + " - Regeling geïmporteerd"); } Messenger.Default.Send(new UpdateTabsEnabledMessage()); RaisePropertyChanged("HasController"); }
public void Clone_Null_ArgumentNullException() { var cloner = new DeepCloner(); var ex = Assert.Throws <ArgumentNullException>(() => cloner.Clone(null)); }
public WhereClause Copy() { return(DeepCloner.Clone(this)); }
/// <summary> /// Set the Primary key Value /// </summary> /// <param name="item"></param> /// <param name="value"></param> /// <returns></returns> public static void SetPrimaryKeyValue(this object item, object value = null) { var prop = DeepCloner.GetFastDeepClonerProperties(item.GetType()).FirstOrDefault(x => x.ContainAttribute <PrimaryKey>()); prop.SetValue(item, MethodHelper.ConvertValue(value, prop.PropertyType)); }
internal static T LoadChildren <T>(T item, ICustomRepository repository, bool onlyFirstLevel = false, List <string> classes = null, List <string> ignoreList = null, Dictionary <long, List <string> > pathLoaded = null, string parentProb = null, long id = 0) where T : class { if (pathLoaded == null) { pathLoaded = new Dictionary <long, List <string> >(); } switch (item) { case null: return(null); case IList _: foreach (var tItem in (IList)item) { var entity = tItem as IDbEntity; if (entity == null) { continue; } LoadChildren(entity, repository, onlyFirstLevel, classes, ignoreList, pathLoaded, parentProb, entity.Id); } break; default: if ((item as IDbEntity) == null) { return(item); } (item as IDbEntity)?.ClearPropertChanges(); var props = FastDeepCloner.DeepCloner.GetFastDeepClonerProperties(item.GetType()); id = (item as IDbEntity).Id; foreach (var prop in props.Where(x => !x.IsInternalType && !x.ContainAttribute <ExcludeFromAbstract>())) { var path = string.Format("{0}.{1}", parentProb ?? "", prop.Name).TrimEnd('.').TrimStart('.'); var propCorrectPathName = path?.Split('.').Length >= 2 ? string.Join(".", path.Split('.').Reverse().Take(2).Reverse()) : path; if (classes != null && classes.All(x => x != propCorrectPathName)) { continue; } if (ignoreList != null && ignoreList.Any(x => x == propCorrectPathName)) { continue; } var propValue = prop.GetValue(item); if (propValue != null) { continue; } if (pathLoaded.ContainsKey(id) && pathLoaded[id].Any(x => x == path)) { continue; } if (!pathLoaded.ContainsKey(id)) { pathLoaded.Add(id, new List <string>() { path }); } else if (pathLoaded[id].All(x => x != path)) { pathLoaded[id].Add(path); } var propertyName = prop.Name; if (path?.Split('.').Length >= 2) { propertyName = string.Join(".", path.Split('.').Reverse().Take(3).Reverse()) + "." + parentProb.Split('.').Last() + "." + propertyName; } var ttype = prop.PropertyType.GetActualType(); var key = props.FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == ttype); if (key == null) { var column = DeepCloner.GetFastDeepClonerProperties(ttype).FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == item.GetType()); var primaryKey = MethodHelper.GetPrimaryKey(item as IDbEntity); if (column == null || primaryKey == null) { continue; } var keyValue = primaryKey.GetValue(item).ConvertValue <long?>(); if (!keyValue.HasValue) { continue; } var result = GetByColumn(keyValue.Value, column.Name, repository, prop.PropertyType); prop.SetValue(item, result); if (result != null && !onlyFirstLevel) { LoadChildren(result, repository, onlyFirstLevel, classes, ignoreList, pathLoaded, propertyName, id); } (item as IDbEntity)?.ClearPropertChanges(); } else { var keyValue = MethodHelper.ConvertValue <long?>(key.GetValue(item)); if (!keyValue.HasValue) { continue; } var result = GetSqlById(keyValue.Value, repository, prop.PropertyType); prop.SetValue(item, result); if (result != null && !onlyFirstLevel) { LoadChildren(result, repository, onlyFirstLevel, classes, ignoreList, pathLoaded, propertyName, id); } (item as IDbEntity)?.ClearPropertChanges(); } } break; } return(item); }
internal static long SaveObject(ICustomRepository repository, InterFace.IDbEntity o, bool isIndependentData = false, bool commit = false) { repository.CreateTransaction(); try { var updateOnly = o.State == ItemState.Changed; o.State = ItemState.Added;// reset State var props = DeepCloner.GetFastDeepClonerProperties(o.GetType()); var primaryKey = MethodHelper.GetPrimaryKey(o); var availableColumns = repository.ObjectColumns(o.GetType()); var objectRules = o.GetType().GetCustomAttribute <Rule>(); var tableName = o.GetType().GetCustomAttribute <Table>()?.Name ?? o.GetType().Name; object dbTrigger = null; if (objectRules != null && !CachedIDbRuleTrigger.ContainsKey(o.GetType())) { dbTrigger = Activator.CreateInstance(objectRules.RuleType) as object; CachedIDbRuleTrigger.Add(o.GetType(), dbTrigger); } else if (objectRules != null) { dbTrigger = CachedIDbRuleTrigger[o.GetType()]; } if (primaryKey == null) { return(0); } var value = primaryKey.GetValue(o).ConvertValue <long?>(); if (value <= 0) { value = null; } else if (value.HasValue && !updateOnly) { var data = Select(repository, o.GetType(), Querys.Where(repository.GetDataBaseType() == DataBaseTypes.Sqllight).Column(primaryKey.GetPropertyName()).Equal(value.Value).ToQueryItem).Rows.FirstOrDefault(); if (data != null) { o.Merge(data.ToObject(o.GetType()) as InterFace.IDbEntity); } } if (!updateOnly) { dbTrigger?.GetType().GetMethod("BeforeSave").Invoke(dbTrigger, new List <object>() { repository, o }.ToArray()); // Check the Rule before save } o.State = ItemState.Added; // reset State var sql = "UPDATE [" + (o.GetType().GetCustomAttribute <Table>()?.Name ?? o.GetType().Name) + "] SET "; var cols = props.Where(x => availableColumns.FindByPrimaryKey <bool>(x.GetPropertyName()) && x.IsInternalType && x.GetCustomAttribute <ExcludeFromAbstract>() == null && x.GetCustomAttribute <PrimaryKey>() == null); if (!value.HasValue) { sql = "INSERT INTO [" + tableName + "](" + string.Join(",", cols.Select(x => "[" + x.GetPropertyName() + "]")) + ") Values("; sql += string.Join(",", cols.Select(x => "@" + x.GetPropertyName())) + ");"; sql += repository.GetDataBaseType() == DataBaseTypes.Sqllight ? " select last_insert_rowid();" : " SELECT IDENT_CURRENT('" + tableName + "');"; } else { sql += string.Join(",", cols.Select(x => "[" + x.GetPropertyName() + "]" + " = @" + MethodHelper.GetPropertyName(x))); sql += Querys.Where(repository.GetDataBaseType() == DataBaseTypes.Sqllight).Column(primaryKey.GetPropertyName()).Equal(value).Execute(); } var cmd = repository.GetSqlCommand(sql); foreach (var col in cols) { var v = col.GetValue(o); if (col.ContainAttribute <ForeignKey>() && MethodHelper.ConvertValue <long?>(v) == 0) { var ob = props.FirstOrDefault(x => x.PropertyType == col.GetCustomAttribute <ForeignKey>().Type); var obValue = ob?.GetValue(o) as InterFace.IDbEntity; var independentData = ob?.GetCustomAttribute <IndependentData>() != null; if (obValue != null) { v = MethodHelper.ConvertValue <long>(MethodHelper.GetPrimaryKey(obValue).GetValue(obValue)) <= 0 ? SaveObject(repository, obValue, independentData) : MethodHelper.ConvertValue <long>(MethodHelper.GetPrimaryKey(obValue).GetValue(obValue)); } } repository.AddInnerParameter(cmd, col.GetPropertyName(), v, repository.GetSqlType(col.PropertyType)); } if (!value.HasValue) { value = MethodHelper.ConvertValue <long>(repository.ExecuteScalar(cmd)); } else { repository.ExecuteNonQuery(cmd); } if (updateOnly) { return(value.Value); } dbTrigger?.GetType().GetMethod("AfterSave").Invoke(dbTrigger, new List <object>() { repository, o, value.Value }.ToArray()); // Check the Rule before save primaryKey.SetValue(o, value); foreach (var prop in props.Where(x => !x.IsInternalType && x.GetCustomAttribute <ExcludeFromAbstract>() == null)) { var independentData = prop.GetCustomAttribute <IndependentData>() != null; var type = prop.PropertyType.GetActualType(); var oValue = prop.GetValue(o); if (oValue == null) { continue; } if (oValue is IList) { foreach (var item in (IList)oValue) { if (DeepCloner.GetFastDeepClonerProperties(item.GetType()).Any(x => x.GetCustomAttribute <ForeignKey>()?.Type == o.GetType())) { DeepCloner.GetFastDeepClonerProperties(item.GetType()).First(x => x.GetCustomAttribute <ForeignKey>()?.Type == o.GetType()).SetValue(item, value); } var res = SaveObject(repository, item as InterFace.IDbEntity, independentData); var foreignKey = FastDeepCloner.DeepCloner.GetFastDeepClonerProperties(o.GetType()).FirstOrDefault(x => x.GetCustomAttribute <ForeignKey>()?.Type == type); if (foreignKey == null || MethodHelper.ConvertValue <long>(foreignKey.GetValue(o)) > 0) { continue; } foreignKey.SetValue(o, res); o.State = ItemState.Changed; } } else { if (DeepCloner.GetFastDeepClonerProperties(oValue.GetType()).Any(x => x.GetCustomAttribute <ForeignKey>()?.Type == o.GetType())) { DeepCloner.GetFastDeepClonerProperties(oValue.GetType()).First(x => x.GetCustomAttribute <ForeignKey>()?.Type == o.GetType()).SetValue(oValue, value); } var res = SaveObject(repository, oValue as InterFace.IDbEntity, independentData); var foreignKey = FastDeepCloner.DeepCloner.GetFastDeepClonerProperties(o.GetType()).FirstOrDefault(x => x.GetCustomAttribute <ForeignKey>()?.Type == type); if (foreignKey == null || MethodHelper.ConvertValue <long>(foreignKey.GetValue(o)) > 0) { continue; } foreignKey.SetValue(o, res); o.State = ItemState.Changed; } } if (o.State == ItemState.Changed) // a change has been made outside the function Save { SaveObject(repository, o, false); } if (!commit) { return(value.Value); } repository.Commit(); return(value.Value); } catch (Exception e) { repository.Rollback(); throw e; } }
/// <summary> /// Create Instance /// </summary> /// <param name="type"></param> /// <param name="uninitializedObject"> true for FormatterServices.GetUninitializedObject and false for Activator.CreateInstance </param> /// <returns></returns> public static object CreateInstance(this Type type, bool uninitializedObject = false) { return(uninitializedObject ? FormatterServices.GetUninitializedObject(type) : DeepCloner.CreateInstance(type)); }
internal static IList DataReaderConverter(Transaction.Transaction repository, IDataReader reader, DbCommandExtended command, Type type) { var tType = type.GetActualType(); var baseListType = typeof(List <>); var listType = baseListType.MakeGenericType(tType); var iList = DeepCloner.CreateInstance(listType) as IList; //#if (NETSTANDARD2_0 || NETSTANDARD1_3 || NETSTANDARD1_5) var props = DeepCloner.GetFastDeepClonerProperties(tType); //#endif try { while (reader.Read()) { object item = null; object clItem = null; //#if (NETSTANDARD2_0 || NETSTANDARD1_3 || NETSTANDARD1_5) item = DeepCloner.CreateInstance(tType); clItem = DeepCloner.CreateInstance(tType); var col = 0; while (col < reader.FieldCount) { var columnName = reader.GetName(col); var value = reader[columnName]; var prop = DeepCloner.GetProperty(tType, columnName); if (prop == null) { prop = props.FirstOrDefault(x => string.Equals(x.GetPropertyName(), columnName, StringComparison.CurrentCultureIgnoreCase) || x.GetPropertyName().ToLower() == columnName); } if (value != null && prop != null && prop.CanRead) { if (value as byte[] != null && prop.PropertyType.FullName.Contains("Guid")) { value = new Guid(value as byte[]); } var dataEncode = prop.GetCustomAttribute <DataEncode>(); var toBase64String = prop.GetCustomAttribute <ToBase64String>(); if (toBase64String != null) { if (value.ConvertValue <string>().IsBase64String()) { value = MethodHelper.DecodeStringFromBase64(value.ConvertValue <string>()); } } else if (dataEncode != null) { value = new DataCipher(dataEncode.Key, dataEncode.KeySize).Decrypt(value.ConvertValue <string>()); } else { value = MethodHelper.ConvertValue(value, prop.PropertyType); } prop.SetValue(item, value); prop.SetValue(clItem, value); } col++; } //#else // var cmReader = new DataRecordExtended(reader); // if (!CachedDataRecord.ContainsKey(tType)) // CachedDataRecord.GetOrAdd(tType, DynamicBuilder.CreateBuilder(cmReader, tType)); // var x = CachedDataRecord[tType]; // item = x.Build(cmReader); // clItem = !(repository?.IsAttached(item) ?? true) ? x.Build(cmReader) : null; //#endif if (clItem != null && !(repository?.IsAttached(clItem) ?? true)) { repository?.AttachNew(clItem); } iList.Add(item); } } catch (Exception e) { throw e; } finally { reader.Close(); reader.Dispose(); if (repository.OpenedDataReaders.ContainsKey(reader)) { repository.OpenedDataReaders.Remove(reader); } } return(iList); }
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); }
public SelectQueryBuilder Clone() { return(DeepCloner.Clone(this)); }
private void ImportButton_OnClick(object sender, RoutedEventArgs e) { if (SignaalPlan == null || !File.Exists(FileTextBox.File)) { this.Close(); } var plcopy = DeepCloner.DeepClone(SignaalPlan); var error = false; try { var ext = Path.GetExtension(FileTextBox.File.ToLower()); switch (ext) { case ".csv": var lines = File.ReadAllLines(FileTextBox.File); var iState = 0; foreach (var s in lines) { if (iState == 0) { if (s.Contains("CYCLUSTIJD")) { iState = 1; } if (s.Contains("FASENDIAGRAMSIGNAALGROEPEN")) { iState = 2; } continue; } if (iState == 1) { var parts = s.Split('"'); SignaalPlan.Cyclustijd = int.Parse(parts[1]); iState = 0; } else if (iState == 2) { iState++; } else if (iState == 3 && !string.IsNullOrWhiteSpace(s)) { string[] parts = s.Split('"'); string strPhase = parts[1]; bool found = false; foreach (var fc in SignaalPlan.Fasen) { var nfc = fc.FaseCyclus.Replace("fc", ""); if (nfc.PadLeft(strPhase.Length, '0') == strPhase) { if (fc.B1 == 0) { fc.B1 = int.Parse(parts[5]); fc.D1 = int.Parse(parts[7]); } else { fc.B2 = int.Parse(parts[5]); fc.D2 = int.Parse(parts[7]); } found = true; break; } } if (!found) { MessageBox.Show("Fout in plan uit bestand " + FileTextBox.File + ".\nNiet alle fasen uit het bestand zitten in de regelaar.", "Fout in plan"); SignaalPlan = plcopy; this.Close(); return; } } else if (string.IsNullOrWhiteSpace(s)) { iState = 0; } } if (SignaalPlan.Fasen.Any(x => x.B1 == 0 || x.D1 == 0)) { MessageBox.Show("Fout in plan uit bestand " + FileTextBox.File + ".\nNiet alle fasen uit de regelaar zijn gevonden.", "Fout in plan"); SignaalPlan = plcopy; this.Close(); return; } break; case ".c": break; } this.Close(); } catch (Exception ee) { MessageBox.Show( "Fout bij inlezen bestand " + FileTextBox.File + ". Is het elders open?\nOriginele error:\n" + ee.ToString(), "Error bij lezen bestand"); SignaalPlan = plcopy; this.Close(); } }
public static DynamicBuilder CreateBuilder(DataRecordExtended dataRecord, Type type) { var props = DeepCloner.GetFastDeepClonerProperties(type); DynamicBuilder dynamicBuilder = new DynamicBuilder(); DynamicMethod method = new DynamicMethod("DynamicCreate", type, new Type[] { typeof(DataRecordExtended) }, type, true); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal(type); generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for (int i = 0; i < dataRecord.FieldCount; i++) { var columnName = dataRecord.GetName(i); var prop = DeepCloner.GetProperty(type, columnName); if (prop == null) { prop = props.FirstOrDefault(x => x.GetPropertyName() == columnName); } if (prop != null && prop.PropertySetValue != null) { var propType = prop.PropertyType; if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable <>)) { propType = propType.GetGenericArguments()?.FirstOrDefault() ?? propType; } var dataEncode = prop.GetCustomAttribute <DataEncode>(); var toBase64String = prop.GetCustomAttribute <ToBase64String>(); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Ldstr, dataEncode?.Key ?? ""); generator.Emit(OpCodes.Ldstr, dataEncode?.KeySize.ToString() ?? ""); generator.Emit(OpCodes.Ldc_I4, toBase64String != null ? 1 : 0); generator.Emit(OpCodes.Ldstr, propType.ToString()); generator.Emit(OpCodes.Ldstr, dataRecord.GetFieldType(i).ToString()); generator.Emit(OpCodes.Ldstr, prop.PropertyType.AssemblyQualifiedName); generator.Emit(OpCodes.Callvirt, getValueMethod); generator.Emit(OpCodes.Unbox_Any, prop.PropertyType); generator.Emit(OpCodes.Callvirt, prop.PropertySetValue); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); return(dynamicBuilder); }
protected object VisitMember(MemberExpression m, bool columnOnly) { try { if (m.Expression != null && m.Expression.NodeType == ExpressionType.Constant && (_overridedNodeType == null)) { VisitConstantFixed(m.Expression as ConstantExpression, m.Member?.Name); return(m); } else if (m.Expression?.ToString().Contains("DisplayClass") ?? false) { CleanDecoder(ValuetoSql(Expression.Lambda(m).Compile().DynamicInvoke())); return(m); } else if (m.Expression != null && (m.Expression.NodeType == ExpressionType.Parameter || (m.ToString().EndsWith(".HasValue") && m.Expression.NodeType == ExpressionType.MemberAccess)) && (_overridedNodeType == null)) { var hasValueAttr = m.ToString().EndsWith(".HasValue"); _overridedNodeType = null; var cl = hasValueAttr ? (m.Expression as MemberExpression).Expression.Type : m.Expression.Type; var prop = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.Name == (hasValueAttr ? (m.Expression as MemberExpression).Member.Name : m.Member.Name)); var name = prop.GetPropertyName(); var table = cl.TableName().GetName(DataBaseTypes); var columnName = string.Format("{0}.[{1}]", table, name).CleanValidSqlName(DataBaseTypes); var dataEncode = prop.GetCustomAttribute <DataEncode>(); if (columnOnly) { return(columnName); } bool isNot = sb.ToString().EndsWith("NOT "); if (prop.PropertyType.IsEnum && prop.ContainAttribute <Stringify>()) { if (!SavedTypes.ContainsKey(prop.FullName)) { SavedTypes.TryAdd(prop.FullName, prop.PropertyType); } columnName += stringyFy.Replace("#", prop.FullName); } if (isNot) { if (!hasValueAttr) { columnName = $"(CASE WHEN {columnName} = 0 THEN 1 ELSE 0 END) {boolString.Replace("#", "0")}"; } else { columnName = $"(CASE WHEN {columnName} IS NULL THEN 1 ELSE 0 END) {boolString.Replace("#", "0")}"; } } else if (hasValueAttr) { columnName = $"(CASE WHEN {columnName} IS NULL THEN 0 ELSE 1 END) {boolString.Replace("#", "1")}"; } else if (prop.PropertyType == typeof(bool) || prop.PropertyType == typeof(bool?)) { columnName = columnName + boolString.Replace("#", "1"); } if (dataEncode != null) { columnName = columnName + dataEncodeString.Replace("#", dataEncode.Key + "|" + ((int)dataEncode.KeySize).ToString()); } sb.Append(columnName); return(m); } else if (m.Expression != null && (m.Expression.NodeType == ExpressionType.MemberAccess)) { _overridedNodeType = null; var key = string.Join("", m.ToString().Split('.').Take(m.ToString().Split('.').Length - 1)); var cl = m.Expression.Type; if (cl.IsInterface) { var pr = (m.Expression as MemberExpression).Expression.Type; var tb = m.Expression.ToString().Split('.').Last(); cl = DeepCloner.GetProperty(pr, tb)?.PropertyType ?? cl; } var prop = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.Name == m.Member.Name); var name = prop.GetPropertyName(); var table = cl.TableName(); var randomTableName = JoinClauses.ContainsKey(key) ? JoinClauses[key].Item1 : RandomKey(); var primaryId = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.ContainAttribute <PrimaryKey>()).GetPropertyName(); var columnName = string.Format("[{0}].[{1}]", randomTableName, name).CleanValidSqlName(DataBaseTypes); if (columnOnly) { return(columnName); } sb.Append(columnName); if (JoinClauses.ContainsKey(key)) { return(m); } // Ok lets build inner join var parentType = (m.Expression as MemberExpression).Expression.Type; var parentTable = parentType.TableName(); prop = DeepCloner.GetFastDeepClonerProperties(parentType).FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == cl); var v = ""; if (prop != null) { v += string.Format("LEFT JOIN {0} {1} ON [{2}].[{3}] = {4}.[{5}]", table.GetName(DataBaseTypes), randomTableName, randomTableName, primaryId, parentTable.GetName(DataBaseTypes), prop.GetPropertyName()).CleanValidSqlName(DataBaseTypes); } else { prop = DeepCloner.GetFastDeepClonerProperties(cl).FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == parentType); if (prop != null) { v += string.Format("LEFT JOIN {0} {1} ON [{2}].[{3}] = {4}.[{5}]", table.GetName(DataBaseTypes), randomTableName, randomTableName, prop.GetPropertyName(), parentTable.GetName(DataBaseTypes), primaryId).CleanValidSqlName(DataBaseTypes); } } if (string.IsNullOrEmpty(v)) { sb = sb.Remove(sb.Length - columnName.Length, columnName.Length); CleanDecoder(ValuetoSql(GetValue(m))); } else { JoinClauses.TryAdd(key, new Tuple <string, string>(randomTableName, v)); } return(m); } else if (m.Expression != null && _overridedNodeType == ExpressionType.MemberAccess) { _overridedNodeType = null; var key = string.Join("", m.ToString().Split('.').Take(m.ToString().Split('.').Length - 1)); var cl = m.Expression.Type; if (cl.IsInterface) { var pr = (m.Expression as MemberExpression).Expression.Type.GetActualType(); var tb = m.Expression.ToString().Split('.').Last(); cl = DeepCloner.GetProperty(pr, tb)?.PropertyType ?? cl; } var prop = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.Name == m.Member.Name); var table = cl.TableName(); var randomTableName = JoinClauses.ContainsKey(key) ? JoinClauses[key].Item1 : RandomKey(); var primaryId = DeepCloner.GetFastDeepClonerProperties(cl).First(x => x.ContainAttribute <PrimaryKey>()).GetPropertyName(); if (JoinClauses.ContainsKey(key)) { return(m); } // Ok lets build inner join var parentType = (m as MemberExpression).Type.GetActualType(); var parentTable = parentType.TableName(); prop = DeepCloner.GetFastDeepClonerProperties(parentType).FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == cl); var v = ""; if (prop != null) { v += string.Format("INNER JOIN {0} {1} ON {2}.[{3}] = [{4}].[{5}]", parentTable.GetName(DataBaseTypes), randomTableName, table.GetName(DataBaseTypes), primaryId, randomTableName, prop.GetPropertyName()).CleanValidSqlName(DataBaseTypes); } else { throw new EntityException(string.Format("Expression STRUCTURE IS NOT SUPPORTED MEMBER{0} for EntityWorker", m.Member.Name)); } if (!string.IsNullOrEmpty(v)) { JoinClauses.TryAdd(key, new Tuple <string, string>(randomTableName, v)); } return(m); } } catch { throw new EntityException(string.Format("Expression '{0}' is not supported", m.ToString())); } if (m.Type.IsInternalType() && m.Expression.NodeType == ExpressionType.Call) { CleanDecoder(ValuetoSql(Expression.Lambda(m).Compile().DynamicInvoke())); return(m); } throw new EntityException(string.Format("The member '{0}' is not supported", m.Member.Name)); }
public void Fulfill(T result, string hash, string description = null) { _promised.Fulfill(result, DeepCloner.DeepClone(result), hash, description); }
public T LoadChildren <T>(T item, bool onlyFirstLevel = false, List <string> classes = null, List <string> ignoreList = null, Dictionary <string, List <string> > pathLoaded = null, string parentProb = null, string id = null) { if (pathLoaded == null) { pathLoaded = new Dictionary <string, List <string> >(); } if (item == null) { return(default(T)); } GlobalConfiguration.Log?.Info("Loading Children for " + item.GetType() + "", item); switch (item) { case IList _: foreach (var tItem in (IList)item) { var entity = tItem; if (entity == null) { continue; } LoadChildren(entity, onlyFirstLevel, classes, ignoreList, pathLoaded, parentProb, entity.GetPrimaryKeyValue().ConvertValue <string>()); } break; default: if ((item) == null) { return(item); } var props = DeepCloner.GetFastDeepClonerProperties(item.GetType()); id = item.GetPrimaryKeyValue().ToString(); foreach (var prop in props.Where(x => x.CanRead && !x.IsInternalType && !x.ContainAttribute <ExcludeFromAbstract>() && !x.ContainAttribute <JsonDocument>() && !x.ContainAttribute <XmlDocument>())) { var path = string.Format("{0}.{1}", parentProb ?? "", prop.Name).TrimEnd('.').TrimStart('.'); var propCorrectPathName = path?.Split('.').Length >= 2 ? string.Join(".", path.Split('.').Reverse().Take(2).Reverse()) : path; if (classes != null && classes.All(x => x != propCorrectPathName)) { continue; } if (ignoreList != null && ignoreList.Any(x => x == propCorrectPathName)) { continue; } var propValue = prop.GetValue(item); if (propValue != null) { if (!(propValue is IList) || (propValue as IList).Any()) { continue; } } if (pathLoaded.ContainsKey(id) && pathLoaded[id].Any(x => x == path)) { continue; } if (!pathLoaded.ContainsKey(id)) { pathLoaded.Add(id, new List <string>() { path }); } else if (pathLoaded[id].All(x => x != path)) { pathLoaded[id].Add(path); } var propertyName = prop.Name; if (path?.Split('.').Length >= 2) { propertyName = string.Join(".", path.Split('.').Reverse().Take(3).Reverse()) + "." + parentProb.Split('.').Last() + "." + propertyName; } var type = prop.PropertyType.GetActualType(); var key = props.FirstOrDefault(x => x.ContainAttribute <ForeignKey>() && x.GetCustomAttribute <ForeignKey>().Type == type && (string.IsNullOrEmpty(x.GetCustomAttribute <ForeignKey>().PropertyName) || x.GetCustomAttribute <ForeignKey>().PropertyName == prop.Name)); if (key == null) { var column = DeepCloner.GetFastDeepClonerProperties(type).FirstOrDefault(x => x.GetCustomAttribute <ForeignKey>()?.Type == item.GetType() && string.IsNullOrEmpty(x.GetCustomAttribute <ForeignKey>().PropertyName)); var primaryKey = item.GetType().GetPrimaryKey(); if (column == null || primaryKey == null) { continue; } var keyValue = primaryKey.GetValue(item); if (keyValue.ObjectIsNew()) { continue; } var result = GetByColumn(keyValue, column.Name, prop.PropertyType); prop.SetValue(item, result); if (result != null && !onlyFirstLevel) { LoadChildren(result, onlyFirstLevel, classes, ignoreList, pathLoaded, propertyName, id); } } else { var isGeneric = prop.PropertyType.GetActualType() != prop.PropertyType; var keyValue = key.GetValue(item); if (keyValue.ObjectIsNew() && !isGeneric) { continue; } object result = null; if (isGeneric && key.GetCustomAttribute <ForeignKey>().Type == item.GetType()) // trying to load children { result = GetByColumn(item.GetPrimaryKeyValue(), key.GetPropertyName(), prop.PropertyType); } else { result = GetById(keyValue, prop.PropertyType); } prop.SetValue(item, result); if (result != null && !onlyFirstLevel) { LoadChildren(result, onlyFirstLevel, classes, ignoreList, pathLoaded, propertyName, id); } } } break; } return(item); }
/// <summary> /// DeSerilize Xml to object, this is supposed to handle all unknow object types but there has not been to many tests. /// </summary> /// <param name="xml"></param> /// <param name="transaction"></param> /// <returns></returns> public static T FromXml <T>(this string xml, IRepository transaction) where T : class { if (string.IsNullOrEmpty(xml)) { return((T)(new object())); } var doc = new System.Xml.XmlDocument(); doc.LoadXml(xml); var o = (T)FromXml(doc.DocumentElement); void LoadXmlIgnoreProperties(object item) { if (item is IList) { foreach (var t in (IList)item) { LoadXmlIgnoreProperties(t); } return; } var type = item?.GetType().GetActualType(); if (type == null) { return; } if (!(item?.GetPrimaryKeyValue().ObjectIsNew() ?? true)) { var primaryId = item.GetPrimaryKeyValue(); foreach (var prop in DeepCloner.GetFastDeepClonerProperties(item.GetType()).Where(x => (x.ContainAttribute <XmlIgnore>() || !x.IsInternalType) && !x.ContainAttribute <ExcludeFromAbstract>() && x.CanReadWrite)) { var value = prop.GetValue(item); if (prop.PropertyType == typeof(string) && string.IsNullOrEmpty(value?.ToString())) { value = string.Empty; } if (prop.IsInternalType && value == LightDataTableShared.ValueByType(prop.PropertyType)) // Value is default { var cmd = transaction.GetSqlCommand($"SELECT [{prop.GetPropertyName()}] FROM {type.TableName().GetName(transaction.DataBaseTypes)} WHERE [{item.GetPrimaryKey().GetPropertyName()}] = {Querys.GetValueByType(item.GetPrimaryKeyValue(), transaction.DataBaseTypes)}"); var data = transaction.ExecuteScalar(cmd); if (data == null) { continue; } if (prop.ContainAttribute <DataEncode>()) { data = new DataCipher(prop.GetCustomAttribute <DataEncode>().Key, prop.GetCustomAttribute <DataEncode>().KeySize).Decrypt(data.ToString()); } else if (prop.ContainAttribute <ToBase64String>() && data.ToString().IsBase64String()) { data = MethodHelper.DecodeStringFromBase64(data.ToString()); } prop.SetValue(item, data.ConvertValue(prop.PropertyType)); } else if (value != null) { LoadXmlIgnoreProperties(value); } } } } if (transaction != null) { LoadXmlIgnoreProperties(o); } return(o); }
private object Save(object o, bool isIndependentData, bool updateOnly = false, List <string> ignoredProperties = null, string lastProperty = null) { try { if (ignoredProperties == null) { ignoredProperties = new List <string>(); } if (lastProperty == null) { lastProperty = string.Empty; // not valid name } GlobalConfiguration.Log?.Info("Save", o); _repository.CreateTransaction(); var props = DeepCloner.GetFastDeepClonerProperties(o.GetType()); var primaryKey = o.GetPrimaryKey(); if (primaryKey == null) { throw new EntityException("Object must have a PrimaryKey"); } var primaryKeyId = !Extension.ObjectIsNew(o.GetPrimaryKeyValue()) ? o.GetPrimaryKeyValue() : null; var availableColumns = _repository.GetColumnSchema(o.GetType()); var objectRules = o.GetType().GetCustomAttribute <Rule>(); var tableName = o.GetType().TableName().GetName(_repository.DataBaseTypes); var primaryKeySubstitut = !primaryKey.GetCustomAttribute <PrimaryKey>().AutoGenerate ? primaryKeyId : null; object dbTrigger = null; if (objectRules != null && !CachedIDbRuleTrigger.ContainsKey(o.GetType())) { dbTrigger = objectRules.RuleType.CreateInstance(); CachedIDbRuleTrigger.Add(o.GetType(), dbTrigger); } else if (objectRules != null || CachedIDbRuleTrigger.ContainsKey(o.GetType())) { dbTrigger = CachedIDbRuleTrigger[o.GetType()]; } if (primaryKeyId != null && !updateOnly) // lets attach the object { var data = GetById(primaryKeyId, o.GetType()); if (data == null) { primaryKeyId = null; o.SetPrimaryKeyValue(); } else { if (!_repository.IsAttached(o)) { _repository.Attach(data); } var changes = _repository.GetObjectChanges(o); foreach (var item in props.Where(x => x.CanRead && !changes.Any(a => a.PropertyName == x.Name) && (x.IsInternalType || x.ContainAttribute <JsonDocument>()))) { item.SetValue(o, item.GetValue(data)); } } } if (!updateOnly) { dbTrigger?.GetType().GetMethod("BeforeSave").Invoke(dbTrigger, new List <object>() { _repository, o }.ToArray()); // Check the Rule before save } object tempPrimaryKey = null; var sql = "UPDATE " + (o.GetType().TableName().GetName(_repository.DataBaseTypes)) + " SET "; var cols = props.FindAll(x => x.CanRead && (availableColumns.ContainsKey(x.GetPropertyName()) || availableColumns.ContainsKey(x.GetPropertyName().ToLower())) && (x.IsInternalType || x.ContainAttribute <JsonDocument>() || x.ContainAttribute <XmlDocument>()) && !x.ContainAttribute <ExcludeFromAbstract>() && x.GetCustomAttribute <PrimaryKey>() == null); // Clean out all unwanted properties if (ignoredProperties.Any()) { cols = cols.FindAll(x => !ignoredProperties.Any(a => a == x.Name || a == (o.GetType().Name + "." + x.Name) || a == (lastProperty + "." + x.Name))); } if (primaryKeyId == null) { if (primaryKey.PropertyType.IsNumeric() && primaryKey.GetCustomAttribute <PrimaryKey>().AutoGenerate) { sql = "INSERT INTO " + tableName + "(" + string.Join(",", cols.Select(x => "[" + x.GetPropertyName() + "]")) + ") Values("; sql += string.Join(",", cols.Select(x => "@" + x.GetPropertyName())) + ");"; sql += _repository.DataBaseTypes == DataBaseTypes.Sqllight ? " select last_insert_rowid();" : (_repository.DataBaseTypes != DataBaseTypes.PostgreSql ? " SELECT IDENT_CURRENT('" + tableName + "');" : " SELECT currval('" + string.Format("{0}_{1}_seq", tableName, primaryKey.GetPropertyName()) + "');"); } else { var colList = new List <IFastDeepClonerProperty>(); tempPrimaryKey = primaryKeySubstitut == null?Guid.NewGuid() : primaryKeySubstitut; if (primaryKeySubstitut == null && primaryKey.PropertyType.IsNumeric()) { tempPrimaryKey = _repository.ExecuteScalar(_repository.GetSqlCommand(String.Format("SELECT MAX([{0}]) FROM {1}", primaryKey.GetPropertyName(), tableName))).ConvertValue <long>() + 1; } else if (primaryKey.PropertyType == typeof(string)) { tempPrimaryKey = tempPrimaryKey.ToString(); } colList.Insert(0, primaryKey); colList.AddRange(cols); sql = "INSERT INTO " + tableName + "(" + string.Join(",", colList.Select(x => "[" + x.GetPropertyName() + "]")) + ") Values("; sql += string.Join(",", colList.Select(x => "@" + x.GetPropertyName())) + "); select '" + tempPrimaryKey + "'"; } } else { sql += string.Join(",", cols.Select(x => "[" + x.GetPropertyName() + "]" + " = @" + x.GetPropertyName())); sql += Querys.Where(_repository.DataBaseTypes).Column(o.GetType().GetActualType().GetPrimaryKey().GetPropertyName()).Equal(primaryKeyId).Execute(); } var cmd = _repository.GetSqlCommand(sql); if ((!primaryKey.PropertyType.IsNumeric() || !primaryKey.GetCustomAttribute <PrimaryKey>().AutoGenerate) && primaryKeyId == null) { _repository.AddInnerParameter(cmd, primaryKey.GetPropertyName(), tempPrimaryKey); } foreach (var col in cols) { var v = col.GetValue(o); var defaultOnEmpty = col.GetCustomAttribute <DefaultOnEmpty>(); if (col.ContainAttribute <ForeignKey>() && (v?.ObjectIsNew() ?? true)) { var ob = props.FirstOrDefault(x => (x.PropertyType == col.GetCustomAttribute <ForeignKey>().Type) && (string.IsNullOrEmpty(col.GetCustomAttribute <ForeignKey>().PropertyName) || col.GetCustomAttribute <ForeignKey>().PropertyName == x.Name)); var obValue = ob?.GetValue(o); var independentData = ob?.GetCustomAttribute <IndependentData>() != null; if (obValue != null) { v = obValue.GetType().GetPrimaryKey().GetValue(obValue)?.ObjectIsNew() ?? true? Save(obValue, independentData, false, ignoredProperties, ob.Name) : obValue.GetType().GetPrimaryKey().GetValue(obValue); col.SetValue(o, v); } } if (col.ContainAttribute <ToBase64String>()) { if (!v?.ConvertValue <string>().IsBase64String() ?? false) { v = MethodHelper.EncodeStringToBase64(v.ConvertValue <string>()); } } if (col.ContainAttribute <JsonDocument>()) { v = v?.ToJson(); } if (col.ContainAttribute <XmlDocument>()) { v = v?.ToXml(); } if (col.ContainAttribute <Stringify>() || col.ContainAttribute <DataEncode>()) { v = v?.ConvertValue <string>(); } if (col.ContainAttribute <DataEncode>()) { if (col.PropertyType != typeof(string)) { throw new EntityException(string.Format("Property {0} Contain DataEncode. PropertyType must be of type String .", col.FullName)); } v = new DataCipher(col.GetCustomAttribute <DataEncode>().Key, col.GetCustomAttribute <DataEncode>().KeySize).Encrypt(v.ToString()); } if (col.ContainAttribute <NotNullable>() && v == null && defaultOnEmpty == null) { throw new EntityException(string.Format("Property {0} dose not allow null.", col.FullName)); } if (v == null && defaultOnEmpty != null) { v = defaultOnEmpty.Value.ConvertValue(col.PropertyType); } _repository.AddInnerParameter(cmd, col.GetPropertyName(), v); } if (primaryKeyId == null) { primaryKeyId = _repository.ExecuteScalar(cmd).ConvertValue(primaryKey.PropertyType); } else { _repository.ExecuteNonQuery(cmd); } var oState = dbTrigger != null?DeepCloner.Clone(o) : null; if (updateOnly) { return(primaryKeyId); } dbTrigger?.GetType().GetMethod("AfterSave").Invoke(dbTrigger, new List <object>() { _repository, o, primaryKeyId }.ToArray()); // Check the Rule before save foreach (var prop in props.Where(x => !x.IsInternalType && !x.ContainAttribute <JsonDocument>() && !x.ContainAttribute <XmlDocument>() && !x.ContainAttribute <ExcludeFromAbstract>())) { var independentData = prop.GetCustomAttribute <IndependentData>() != null; var type = prop.PropertyType.GetActualType(); var oValue = prop.GetValue(o); if (oValue == null) { continue; } var vList = oValue is IList ? (IList)oValue : new List <object>() { oValue }; foreach (var item in vList) { var foreignKey = DeepCloner.GetFastDeepClonerProperties(item.GetType()).FirstOrDefault(x => x.GetCustomAttribute <ForeignKey>()?.Type == o.GetType() && string.IsNullOrEmpty(x.GetCustomAttribute <ForeignKey>().PropertyName)); foreignKey?.SetValue(item, primaryKeyId); var res = Save(item, independentData, false, ignoredProperties, prop.Name); foreignKey = props.FirstOrDefault(x => x.GetCustomAttribute <ForeignKey>()?.Type == type && (x.GetCustomAttribute <ForeignKey>().PropertyName == prop.Name || string.IsNullOrEmpty(x.GetCustomAttribute <ForeignKey>().PropertyName))); if (foreignKey == null || !foreignKey.GetValue(o).ObjectIsNew()) { continue; } if (o.GetType() == foreignKey.GetCustomAttribute <ForeignKey>().Type) { continue; } foreignKey.SetValue(o, res); } } if (oState != null && _repository.GetObjectChanges(o, oState).Count > 0) // a change has been made outside the function Save then resave { o.SetPrimaryKeyValue(primaryKeyId); Save(o, false, true, ignoredProperties); } o.SetPrimaryKeyValue(primaryKeyId); _repository.Attach(o, true); return(primaryKeyId); } catch (Exception e) { GlobalConfiguration.Log?.Error(e); _repository.Rollback(); throw; } }
public static void Clear() { DeepCloner.ClearKnownTypesProcessors(); DeepCloner.ClearPreCloneProcessors(); DeepCloner.ClearPostCloneProcessors(); }
public void RemoveTable(Type tableType, List <Type> tableRemoved = null, bool remove = true) { if (tableRemoved == null) { tableRemoved = new List <Type>(); } if (tableRemoved.Any(x => x == tableType)) { return; } GlobalConfiguration.Log?.Info("Removig", tableType); tableRemoved.Insert(0, tableType); var props = DeepCloner.GetFastDeepClonerProperties(tableType); foreach (var prop in props.Where(x => (!x.IsInternalType || x.ContainAttribute <ForeignKey>()) && !x.ContainAttribute <ExcludeFromAbstract>() && !x.ContainAttribute <JsonDocument>() && !x.ContainAttribute <XmlDocument>())) { var key = prop.GetCustomAttribute <ForeignKey>(); if (key != null && tableRemoved.Any(x => x == key.Type)) { continue; } if (key != null) { RemoveTable(key.Type, tableRemoved, false); } else { RemoveTable(prop.PropertyType.GetActualType(), tableRemoved, false); } } if (!remove) { return; } var tableData = _repository.GetColumnSchema(tableType); if (!tableData.Values.Any()) { return; } var c = tableRemoved.Count; _repository.CreateTransaction(); while (c > 0) { for (var i = tableRemoved.Count - 1; i >= 0; i--) { try { var tType = tableRemoved[i]; if (_repository.GetColumnSchema(tType).Values.Any()) { Database.CachedColumnSchema.Remove(tType.FullName + _repository.DataBaseTypes.ToString()); var tableName = tType.TableName(); _repository.ExecuteNonQuery(_repository.GetSqlCommand("DELETE FROM " + tableName.GetName(_repository.DataBaseTypes) + ";")); var cmd = _repository.GetSqlCommand("DROP TABLE " + tableName.GetName(_repository.DataBaseTypes) + ";"); _repository.ExecuteNonQuery(cmd); Database.CachedColumnSchema.Remove(tType.FullName + _repository.DataBaseTypes.ToString()); } c--; } catch (Exception e) { if (_repository.DataBaseTypes == DataBaseTypes.PostgreSql) { _repository.Renew(); } } } } }
public static void Config() { // Clone 开始时,判断哪些类型是直接使用原对象而不 DeepClone 的 DeepCloner.AddKnownTypesProcessor((type) => { if ( // Celeste Singleton type == typeof(Celeste) || type == typeof(Settings) // Everest || type == typeof(ModAsset) // Monocle || type == typeof(GraphicsDevice) || type == typeof(GraphicsDeviceManager) || type == typeof(Monocle.Commands) || type == typeof(Pooler) || type == typeof(BitTag) || type == typeof(Atlas) || type == typeof(VirtualTexture) // XNA GraphicsResource || type.IsSubclassOf(typeof(GraphicsResource)) ) { return(true); } return(null); }); // Clone 对象的字段前,判断哪些类型是直接使用原对象而不 DeepClone 的 DeepCloner.AddPreCloneProcessor((sourceObj, deepCloneState) => { if (sourceObj is Level) { // 金草莓死亡或者 PageDown/Up 切换房间后等等改变 Level 实例的情况 if (Engine.Scene is Level level) { return(level); } return(sourceObj); } if (sourceObj is Entity entity && entity.TagCheck(Tags.Global) && !(entity is SeekerBarrierRenderer) && !(entity is LightningRenderer) ) { return(sourceObj); } // 稍后重新创建正在播放的 SoundSource 里的 EventInstance 实例 if (sourceObj is SoundSource source && source.Playing && source.GetFieldValue("instance") is EventInstance instance) { if (string.IsNullOrEmpty(source.EventName)) { return(null); } instance.SavePath(source.EventName); instance.SaveTimelinePosition(instance.LoadTimelinePosition()); } // 重新创建正在播放的 EventInstance 实例 if (sourceObj is EventInstance eventInstance && eventInstance.Clone() is EventInstance clonedInstance) { deepCloneState.AddKnownRef(sourceObj, clonedInstance); return(clonedInstance); } return(null); }); // Clone 对象的字段后,进行自定的处理 DeepCloner.AddPostCloneProcessor((sourceObj, clonedObj) => { if (clonedObj == null) { return(null); } // 修复:DeepClone 的 hashSet.Containes(里面存在的引用对象) 总是返回 False,Dictionary 无此问题 if (clonedObj.GetType().IsHashSet(out Type type) && !type.IsSimple()) { IEnumerator enumerator = ((IEnumerable)clonedObj).GetEnumerator(); List <object> backup = new List <object>(); while (enumerator.MoveNext()) { backup.Add(enumerator.Current); } clonedObj.InvokeMethod("Clear"); backup.ForEach(obj => { clonedObj.InvokeMethod("Add", obj); }); } return(clonedObj); }); }
/// <summary> /// generic Json to object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="json"></param> /// <param name="repository"></param> /// <returns></returns> internal static T FromJson <T>(this string json, IRepository repository) { var o = JSON.ToObject <T>(json); void LoadJsonIgnoreProperties(object item) { if (item is IList) { foreach (var t in (IList)item) { LoadJsonIgnoreProperties(t); } return; } var type = item?.GetType().GetActualType(); if (type == null) { return; } if (!(item?.GetPrimaryKeyValue().ObjectIsNew() ?? true)) { var primaryId = item.GetPrimaryKeyValue(); foreach (var prop in DeepCloner.GetFastDeepClonerProperties(item.GetType()).Where(x => (x.ContainAttribute <JsonIgnore>() || !x.IsInternalType) && !x.ContainAttribute <ExcludeFromAbstract>() && x.CanRead)) { var value = prop.GetValue(item); if (prop.PropertyType == typeof(string) && string.IsNullOrEmpty(value?.ToString())) { value = string.Empty; } if (prop.IsInternalType && value == LightDataTableShared.ValueByType(prop.PropertyType)) // Value is default { var cmd = repository.GetSqlCommand($"SELECT [{prop.GetPropertyName()}] FROM {type.TableName().GetName(repository.DataBaseTypes)} WHERE [{item.GetPrimaryKey().GetPropertyName()}] = {Querys.GetValueByType(item.GetPrimaryKeyValue(), repository.DataBaseTypes)}"); var data = repository.ExecuteScalar(cmd); if (data == null) { continue; } if (prop.ContainAttribute <DataEncode>()) { data = new DataCipher(prop.GetCustomAttribute <DataEncode>().Key, prop.GetCustomAttribute <DataEncode>().KeySize).Decrypt(data.ToString()); } else if (prop.ContainAttribute <ToBase64String>() && data.ToString().IsBase64String()) { data = MethodHelper.DecodeStringFromBase64(data.ToString()); } else if (prop.ContainAttribute <JsonDocument>()) { data = data?.ToString().FromJson(prop.PropertyType); } else if (prop.ContainAttribute <XmlDocument>()) { data = data?.ToString().FromXml(); } prop.SetValue(item, data.ConvertValue(prop.PropertyType)); } else if (value != null) { LoadJsonIgnoreProperties(value); } } } } LoadJsonIgnoreProperties(o); return(o); }
internal static void RemoveTable(ICustomRepository repository, Type tableType, bool commit = false, List <Type> tableRemoved = null, bool remove = true) { if (commit) { repository.CreateTransaction(); } if (tableRemoved == null) { tableRemoved = new List <Type>(); } if (tableRemoved.Any(x => x == tableType)) { return; } tableRemoved.Insert(0, tableType); var props = DeepCloner.GetFastDeepClonerProperties(tableType); foreach (var prop in props.Where(x => (!x.IsInternalType || x.ContainAttribute <ForeignKey>()) && !x.ContainAttribute <ExcludeFromAbstract>())) { var key = prop.GetCustomAttribute <ForeignKey>(); if (key != null && tableRemoved.Any(x => x == key.Type)) { continue; } if (key != null) { RemoveTable(repository, key.Type, commit, tableRemoved, false); } else { RemoveTable(repository, prop.PropertyType.GetActualType(), commit, tableRemoved, false); } } if (!remove) { return; } var tableData = ObjectColumns(repository, tableType); if (!tableData.Rows.Any()) { return; } var c = tableRemoved.Count; while (c > 0) { for (var i = tableRemoved.Count - 1; i >= 0; i--) { try { var tType = tableRemoved[i]; CachedObjectColumn.Remove(tType); var tableName = tType.GetCustomAttribute <Table>()?.Name ?? tType.Name; var cmd = repository.GetSqlCommand("DROP TABLE [" + tableName + "];"); repository.ExecuteNonQuery(cmd); c--; } catch { } } } if (commit) { repository.Commit(); } }