public static DataObject GetEditableByPrimaryKey(Type dataObjectType, long?primaryKey, ITransaction transaction, IEnumerable <string> readOnlyFields) { DataObject dataObject = (DataObject)Activator.CreateInstance(dataObjectType); dataObject.isInsert = false; SchemaObject schemaObject = Schema.Schema.GetSchemaObject(dataObjectType); int tableAliasCounter = 1; Dictionary <string, string> tableAliasesByFieldPath = new Dictionary <string, string>() { { "", "table000" } }; ISelectQuery selectQuery = SQLProviderFactory.GetSelectQuery(); foreach (Schema.Field field in schemaObject.GetFields()) { Select select = new Select() { SelectOperand = (Base.Data.Operand.Field) $"table000.{field.FieldName}", Alias = $"table000_{field.FieldName}" }; selectQuery.SelectList.Add(select); } IOrderedEnumerable <string> sortedFields = readOnlyFields.Where(f => f.Contains('.')).OrderBy(f => f); foreach (string readOnlyField in sortedFields) { string[] parts = readOnlyField.Split('.'); string checkedPath = ""; DataObject lastDataObject = dataObject; SchemaObject lastSchemaObject = schemaObject; for (int i = 0; i < parts.Length - 1; i++) { string myAlias = tableAliasesByFieldPath[checkedPath]; if (!string.IsNullOrEmpty(checkedPath)) { checkedPath += "."; } checkedPath += parts[i]; if (tableAliasesByFieldPath.ContainsKey(checkedPath)) { continue; } tableAliasCounter++; string newAlias = $"table{tableAliasCounter.ToString("D3")}"; tableAliasesByFieldPath.Add(checkedPath, newAlias); Relationship relationship = lastSchemaObject.GetRelationship(parts[i]); DataObject relatedDataObject = relationship.GetValue(lastDataObject); if (relatedDataObject == null) { relatedDataObject = (DataObject)Activator.CreateInstance(relationship.RelatedObjectType); relatedDataObject.isEditable = false; relationship.SetPrivateDataCallback(lastDataObject, relatedDataObject); } Join join = new Join(); join.JoinType = Join.JoinTypes.Left; join.Table = new Table(relationship.RelatedSchemaObject.SchemaName, relationship.RelatedSchemaObject.ObjectName, newAlias); join.Condition = lastDataObject.GetRelationshipCondition(relationship, myAlias, newAlias); selectQuery.JoinList.Add(join); lastDataObject = relatedDataObject; lastSchemaObject = relationship.RelatedSchemaObject; } string path = readOnlyField.Substring(0, readOnlyField.LastIndexOf('.')); string pathField = readOnlyField.Substring(readOnlyField.LastIndexOf('.') + 1); string finalAlias = tableAliasesByFieldPath[path]; Select readOnlySelect = new Select() { SelectOperand = (Base.Data.Operand.Field) $"{path}.{pathField}", Alias = $"{path}_{pathField}" }; selectQuery.SelectList.Add(readOnlySelect); } selectQuery.WhereCondition = new Condition() { Left = (Base.Data.Operand.Field) $"table000_{schemaObject.PrimaryKeyField.FieldName}", ConditionType = Condition.ConditionTypes.Equal, Right = new Literal(primaryKey) }; DataTable dataTable = selectQuery.Execute(transaction); if (dataTable.Rows.Count <= 0) { return(null); } DataRow row = dataTable.Rows[0]; foreach (Schema.Field field in schemaObject.GetFields()) { object value = row[$"table000_{field.FieldName}"]; field.SetPrivateDataCallback(dataObject, value); dataObject.retrievedPaths.Add(field.FieldName); } foreach (string readOnlyField in sortedFields) { string path = readOnlyField.Substring(0, readOnlyField.LastIndexOf('.')); string pathField = readOnlyField.Substring(readOnlyField.LastIndexOf('.') + 1); string alias = tableAliasesByFieldPath[path]; object value = row[$"{alias}_{pathField}"]; DataObject lastObject = dataObject; SchemaObject lastSchemaObject = schemaObject; string[] parts = path.Split('.'); for (int i = 0; i < parts.Length; i++) { lastObject.retrievedPaths.Add(parts[i]); Relationship relationship = lastSchemaObject.GetRelationship(parts[i]); lastObject = relationship.GetValue(lastObject); lastSchemaObject = relationship.RelatedSchemaObject; } Schema.Field field = lastSchemaObject.GetField(pathField); field.SetPrivateDataCallback(lastObject, value); lastObject.retrievedPaths.Add(pathField); } return(dataObject); }
public static TDataObject GetReadOnlyByPrimaryKey <TDataObject>(long?primaryKey, ITransaction transaction, IEnumerable <string> fields) where TDataObject : DataObject { DataObject dataObject = Activator.CreateInstance <TDataObject>(); dataObject.isEditable = false; SchemaObject thisSchemaObject = Schema.Schema.GetSchemaObject <TDataObject>(); IOrderedEnumerable <string> sortedFields = fields.Where(f => f.Contains(".")).OrderBy(str => str); Dictionary <string, string> tableAliasesForFieldPath = new Dictionary <string, string>() { { "", "table000" } }; int tableAliasCounter = 1; List <Join> joinList = new List <Join>(); foreach (string fieldPath in sortedFields.Where(f => f.Contains(".")).Select(f => f.Substring(0, f.LastIndexOf(".")))) { string[] fieldPathParts = fieldPath.Split('.'); string checkedFieldPath = ""; DataObject lastObject = dataObject; SchemaObject lastSchemaObject = thisSchemaObject; for (int i = 0; i < fieldPathParts.Length - 1; i++) { string myAlias = tableAliasesForFieldPath[checkedFieldPath]; if (!string.IsNullOrEmpty(checkedFieldPath)) { checkedFieldPath += "."; } checkedFieldPath += fieldPathParts[i]; if (tableAliasesForFieldPath.ContainsKey(checkedFieldPath)) { continue; } Relationship relationship = lastSchemaObject.GetRelationship(checkedFieldPath); SchemaObject relatedSchemaObject = relationship.RelatedSchemaObject; DataObject relatedDataObject = relationship.GetValue(lastObject); if (relatedDataObject == null) { relatedDataObject = (DataObject)Activator.CreateInstance(relationship.RelatedObjectType); relatedDataObject.isEditable = false; relationship.SetPrivateDataCallback(lastObject, relatedDataObject); } tableAliasCounter++; string otherAlias = $"table{tableAliasCounter.ToString("D3")}"; tableAliasesForFieldPath.Add(checkedFieldPath, otherAlias); Join join = new Join(); join.Table = new Table(relatedSchemaObject.SchemaName, relatedSchemaObject.ObjectName, otherAlias); join.JoinType = Join.JoinTypes.Left; join.Condition = lastObject.GetRelationshipCondition(relationship, myAlias, otherAlias); lastObject = relatedDataObject; lastSchemaObject = relatedSchemaObject; } } ISelectQuery selectQuery = SQLProviderFactory.GetSelectQuery(); selectQuery.JoinList = joinList; foreach (string field in sortedFields) { string path = ""; string fieldName = ""; if (field.Contains('.')) { path = field.Substring(0, field.LastIndexOf('.')); fieldName = field.Substring(field.LastIndexOf('.') + 1); } else { fieldName = field; } string alias = tableAliasesForFieldPath[path]; Select select = new Select() { SelectOperand = (Base.Data.Operand.Field) $"{alias}.{fieldName}", Alias = $"{alias}_{fieldName}" }; selectQuery.SelectList.Add(select); } selectQuery.WhereCondition = new Condition() { Left = (Base.Data.Operand.Field)("table000_" + thisSchemaObject.PrimaryKeyField.FieldName), ConditionType = Condition.ConditionTypes.Equal, Right = new Literal(primaryKey) }; DataTable dataTable = selectQuery.Execute(transaction); if (dataTable.Rows.Count <= 0) { return(null); } DataRow row = dataTable.Rows[0]; foreach (string field in sortedFields) { DataObject lastObject = dataObject; SchemaObject lastSchemaObject = thisSchemaObject; if (field.Contains('.')) { string[] parts = field.Split('.'); for (int i = 0; i < parts.Length - 1; i++) { lastObject.retrievedPaths.Add(parts[i]); Relationship relationship = lastSchemaObject.GetRelationship(parts[i]); lastObject = relationship.GetValue(lastObject); lastSchemaObject = relationship.RelatedSchemaObject; } } string path = ""; string pathField = ""; if (field.Contains('.')) { path = field.Substring(0, field.LastIndexOf('.')); pathField = field.Substring(field.LastIndexOf('.')); } else { pathField = field; } string alias = tableAliasesForFieldPath[path]; object value = row[$"{alias}_{pathField}"]; lastSchemaObject.GetField(pathField).SetPrivateDataCallback(lastObject, value); lastObject.retrievedPaths.Add(pathField); } return((TDataObject)dataObject); }