public void Copy(DataObject destination) { if (destination.GetType() != GetType()) { throw new InvalidOperationException("Cannot copy to Data Object of different type"); } SchemaObject schemaObject = Schema.Schema.GetSchemaObject(GetType()); foreach (Schema.Field field in schemaObject.GetFields().Where(f => f != schemaObject.PrimaryKeyField)) { field.SetPrivateDataCallback(destination, field.GetPrivateDataCallback(this)); } }
public void Copy(DataObject destination) { if (destination.GetType() != GetType()) { throw new InvalidOperationException("Cannot copy to Data Object of different type"); } SchemaObject schemaObject = Schema.Schema.GetSchemaObject(GetType()); Dictionary <string, object> destinationOriginalValues = destination.originalValues.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); foreach (Schema.Field field in schemaObject.GetFields().Where(f => f != schemaObject.PrimaryKeyField)) { field.SetPrivateDataCallback(destination, field.GetPrivateDataCallback(this)); } // Restore destination original values, a Copy means we're changing things destination.originalValues = destinationOriginalValues; }
//public void SetData(IEnumerable<string> fieldsToSet, Dictionary<string, Tuple<ISelectQuery, Dictionary<string, string>>> queries, DataRow row) //{ // if (!IsEditable) // { // throw new ReadOnlyException("Cannot call SetData on a read-only Data Object"); // } // SchemaObject schemaObject = Schema.Schema.GetSchemaObject(GetType()); // foreach (IGrouping<string, string> fieldByPath in fieldsToSet.GroupBy(field => // { // if (field.Contains(".")) // { // return field.Substring(0, field.LastIndexOf('.')); // } // return string.Empty; // })) // { // DataObject objectToSetValueOn = this; // if (fieldByPath.Key.Contains(".")) // { // string[] parts = fieldByPath.Key.Split('.'); // SchemaObject lastSchemaObject = schemaObject; // for (int i = 0; i < parts.Length - 1; i++) // { // Relationship relationship = lastSchemaObject.GetRelationship(parts[i]); // if (relationship != null) // { // DataObject relatedDataObject = relationship.GetValue(objectToSetValueOn); // if (relatedDataObject == null) // { // relatedDataObject = (DataObject)Activator.CreateInstance(relationship.RelatedObjectType); // relationship.SetPrivateDataCallback(objectToSetValueOn, relatedDataObject); // } // objectToSetValueOn = relatedDataObject; // lastSchemaObject = relationship.RelatedSchemaObject; // } // else if (lastSchemaObject.GetRelationshipList(parts[i]) != null) // { // break; // } // } // } // string fieldAlias = tableAliasesByFieldPath[fieldByPath.Key]; // foreach (string field in fieldByPath) // { // string fieldName = field; // if (fieldName.Contains('.')) // { // fieldName = fieldName.Substring(fieldName.LastIndexOf('.') + 1); // } // string columnName = $"{fieldAlias}_{fieldName}"; // object databaseValue = row[columnName]; // databaseValue = databaseValue == DBNull.Value ? null : databaseValue; // Schema.Field schemaField = schemaObject.GetField(field); // schemaField.SetPrivateDataCallback(objectToSetValueOn, databaseValue); // } // } //} public void SetData(IEnumerable <string> fieldsToSet, Dictionary <string, Tuple <ISelectQuery, Dictionary <string, string> > > queries, DataRow outerObjectRow) { IEnumerable <string> fieldsWeCanDoSomethingAbout = fieldsToSet.Where(field => !queries.Keys.Where(k => !string.IsNullOrEmpty(k)).Any(reverseFieldPath => field.StartsWith(reverseFieldPath))); IEnumerable <IGrouping <string, string> > fieldsByFieldPath = fieldsWeCanDoSomethingAbout.OrderBy(field => field).GroupBy(field => field.Contains('.') ? field.Substring(0, field.LastIndexOf('.')) : ""); // Load in all parent relationships foreach (IGrouping <string, string> fieldGroup in fieldsByFieldPath.Where(group => !string.IsNullOrEmpty(group.Key))) { SchemaObject currentSchemaObject = Schema.Schema.GetSchemaObject(GetType()); DataObject currentObject = this; string[] fieldPathParts = fieldGroup.Key.Split('.'); for (int i = 0; i < fieldPathParts.Length; i++) { Relationship relationship = currentSchemaObject.GetRelationship(fieldPathParts[i]); DataObject relatedObject = relationship.GetValue(this); if (relatedObject == null) { relatedObject = (DataObject)Activator.CreateInstance(relationship.RelatedObjectType); relatedObject.isEditable = false; relationship.SetPrivateDataCallback(currentObject, relatedObject); } currentSchemaObject = relationship.RelatedSchemaObject; currentObject = relatedObject; } } Dictionary <string, string> tableAliasesForOuterRow = queries[""].Item2; // Set data on this object or parent objects foreach (IGrouping <string, string> fieldGroup in fieldsByFieldPath) { string tableAlias = tableAliasesForOuterRow[fieldGroup.Key]; DataObject dataObjectToSet = this; SchemaObject schemaObjectToSet = Schema.Schema.GetSchemaObject(GetType()); if (!string.IsNullOrEmpty(fieldGroup.Key)) { string[] fieldPathParts = fieldGroup.Key.Split('.'); for (int i = 0; i < fieldPathParts.Length; i++) { Relationship relationship = schemaObjectToSet.GetRelationship(fieldPathParts[i]); dataObjectToSet = relationship.GetValue(dataObjectToSet); schemaObjectToSet = Schema.Schema.GetSchemaObject(dataObjectToSet.GetType()); } } foreach (string field in fieldGroup) { string fieldToSet = field; if (fieldToSet.Contains('.')) { fieldToSet = fieldToSet.Substring(fieldToSet.LastIndexOf('.') + 1); } object value = outerObjectRow[$"{tableAlias}_{fieldToSet}"]; Schema.Field schemaField = schemaObjectToSet.GetField(fieldToSet); schemaField.SetPrivateDataCallback(dataObjectToSet, value); } } // Set data for reverse relationships HashSet <string> handledReverseRelationships = new HashSet <string>(); foreach (string reverseRelationship in queries.Keys.Where(key => !string.IsNullOrEmpty(key))) { string[] reverseRelationshipParts = reverseRelationship.Split('.'); DataObject parentObject = this; SchemaObject parentSchemaObject = Schema.Schema.GetSchemaObject(GetType()); string reverseRelationshipWeCanDoSomethingAbout = ""; RelationshipList relationshipList = null; for (int i = 0; i < reverseRelationshipParts.Length; i++) { Relationship relationship = parentSchemaObject.GetRelationship(reverseRelationshipParts[i]); if (relationship != null) { parentObject = relationship.GetValue(parentObject); parentSchemaObject = relationship.RelatedSchemaObject; reverseRelationshipWeCanDoSomethingAbout += relationship.RelatedSchemaObject.ObjectName + "."; } else { relationshipList = parentSchemaObject.GetRelationshipList(reverseRelationshipParts[i]); reverseRelationshipWeCanDoSomethingAbout += relationshipList.RelationshipListName + "."; break; } } if (!handledReverseRelationships.Add(reverseRelationshipWeCanDoSomethingAbout)) { continue; } long? primaryKey = parentObject.PrimaryKeyField.GetValue(parentObject) as long?; ISelectQuery query = queries[reverseRelationshipWeCanDoSomethingAbout].Item1; Condition primaryKeyCondition = new Condition() { Left = (Base.Data.Operand.Field)relationshipList.ForeignKeyName, ConditionType = Condition.ConditionTypes.Equal, Right = new Literal(primaryKey) }; ICondition previousQueryCondition = query.WhereCondition; if (query.WhereCondition != null) { ConditionGroup conditionGroup = new ConditionGroup() { ConditionGroupType = ConditionGroup.ConditionGroupTypes.And, Conditions = new List <ICondition>() { query.WhereCondition, primaryKeyCondition } }; query.WhereCondition = conditionGroup; } else { query.WhereCondition = primaryKeyCondition; } HashSet <string> childFieldsToSet = fieldsToSet.Where(f => f.StartsWith(reverseRelationshipWeCanDoSomethingAbout)).Select(f => f.Replace(reverseRelationshipWeCanDoSomethingAbout, "")).ToHashSet(); childFieldsToSet.Add(relationshipList.RelatedSchemaObject.PrimaryKeyField.FieldName); Dictionary <string, Tuple <ISelectQuery, Dictionary <string, string> > > childQueries = new Dictionary <string, Tuple <ISelectQuery, Dictionary <string, string> > >(); foreach (KeyValuePair <string, Tuple <ISelectQuery, Dictionary <string, string> > > childQuery in queries.Where(kvp => kvp.Key.StartsWith(reverseRelationshipWeCanDoSomethingAbout))) { childQueries.Add(childQuery.Key.Replace(reverseRelationshipWeCanDoSomethingAbout, ""), childQuery.Value); } object reverseRelationshipList = relationshipList.GetPrivateDataCallback(parentObject); MethodInfo addMethod = reverseRelationshipList.GetType().GetMethod("Add", new Type[] { relationshipList.RelatedObjectType }); DataTable results = query.Execute(null); query.WhereCondition = previousQueryCondition; foreach (DataRow row in results.Rows) { DataObject childObject = (DataObject)Activator.CreateInstance(relationshipList.RelatedObjectType); childObject.isEditable = false; childObject.SetData(childFieldsToSet, childQueries, row); addMethod.Invoke(reverseRelationshipList, new object[] { childObject }); } parentObject.retrievedPaths.Add(relationshipList.RelationshipListName); } }