public override bool Evaluate(DataObject dataObject) { SchemaObject schemaObject = Schema.Schema.GetSchemaObject(dataObject.GetType()); Field schemaField = schemaObject.GetField(field); return(schemaField.GetValue(dataObject) != null); }
public override object Evaluate(Dictionary <string, object> parameters) { string[] parts = field.Split('.'); string objectName = parts[0]; if (!parameters.ContainsKey(objectName)) { throw new KeyNotFoundException("Object with name " + objectName + " not found"); } object latestObject = parameters[objectName]; for (int i = 1; i < parts.Length; i++) { SchemaObject schemaObject = Schema.Schema.GetSchemaObject(latestObject.GetType()); Field field = schemaObject.GetField(parts[i]); if (field != null) { return(field.GetValue((DataObject)latestObject)); } Relationship relationship = schemaObject.GetRelationship(parts[i]); if (relationship == null) { throw new ArgumentException("Could not determine path during Object Expression evaluation"); } latestObject = relationship.GetPrivateDataCallback(latestObject); } return(null); }
public override bool Evaluate(DataObject dataObject) { SchemaObject schemaObject = Schema.Schema.GetSchemaObject(dataObject.GetType()); Field schemaField = schemaObject.GetField(field); object value = schemaField.GetValue(dataObject); if (!(value is string stringValue)) { return(true); } return(stringValue.Length <= maxLength); }
protected virtual List <FKConstraintConflict> GetFKConstraintConflicts(ITransaction transaction) { List <FKConstraintConflict> fKConstraintConflicts = new List <FKConstraintConflict>(); SchemaObject mySchemaObject = Schema.Schema.GetSchemaObject(GetType()); Schema.Field primaryKeyField = mySchemaObject.PrimaryKeyField; foreach (RelationshipList relationshipList in Schema.Schema.GetSchemaObject(GetType()).GetRelationshipLists()) { SchemaObject relatedSchemaObject = Schema.Schema.GetSchemaObject(relationshipList.RelatedObjectType); Schema.Field relatedField = relatedSchemaObject.GetField(relationshipList.ForeignKeyName); ISelectQuery relationshipListQuery = SQLProviderFactory.GetSelectQuery(); relationshipListQuery.SelectList.Add(relatedSchemaObject.PrimaryKeyField.FieldName); relationshipListQuery.Table = new Table(relatedSchemaObject.SchemaName, relatedSchemaObject.ObjectName); relationshipListQuery.WhereCondition = new Condition() { Left = (Base.Data.Operand.Field)relatedField.FieldName, ConditionType = Condition.ConditionTypes.Equal, Right = new Literal(primaryKeyField.GetValue(this)) }; DataTable results = relationshipListQuery.Execute(transaction); foreach (DataRow row in results.Rows) { FKConstraintConflict fKConstraintConflict = new FKConstraintConflict(); fKConstraintConflict.ConflictType = relationshipList.RelatedObjectType; fKConstraintConflict.ForeignKey = row[relatedSchemaObject.PrimaryKeyField.FieldName] as long?; fKConstraintConflict.ForeignKeyName = relatedField.FieldName; fKConstraintConflict.ActionType = relationshipList.AutoDeleteReferences ? FKConstraintConflict.ActionTypes.AutoDeleteReference : relationshipList.AutoRemoveReferences ? FKConstraintConflict.ActionTypes.AutoRemoveReference : FKConstraintConflict.ActionTypes.Conflict; fKConstraintConflicts.Add(fKConstraintConflict); } } return(fKConstraintConflicts); }
//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); } }
public IEnumerable <DataObject> GetUntypedEditableReader(ITransaction transaction, IEnumerable <string> readOnlyFields = null) { SchemaObject schemaObject = Schema.Schema.GetSchemaObject(DataObjectType); HashSet <string> fields = new HashSet <string>(); foreach (Schema.Field field in schemaObject.GetFields()) { fields.Add(field.FieldName); } fields.AddRange(readOnlyFields); ISelectQuery selectQuery = GetBaseQuery(schemaObject, fields, out Dictionary <string, string> tableAliasesByFieldPath); DataTable table = selectQuery.Execute(transaction); FieldInfo isEditableField = DataObjectType.GetField("isEditable", BindingFlags.NonPublic | BindingFlags.Instance); foreach (DataRow row in table.Rows) { DataObject dataObject = (DataObject)Activator.CreateInstance(DataObjectType); isEditableField.SetValue(dataObject, true); foreach (IGrouping <string, string> fieldByPath in fields.GroupBy(field => { if (field.Contains(".")) { return(field.Substring(0, field.LastIndexOf('.'))); } return(string.Empty); })) { DataObject objectToSetValueOn = dataObject; 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]); DataObject relatedDataObject = relationship.GetValue(objectToSetValueOn); if (relatedDataObject == null) { relatedDataObject = (DataObject)Activator.CreateInstance(relationship.RelatedObjectType); relationship.SetPrivateDataCallback(objectToSetValueOn, relatedDataObject); } objectToSetValueOn = relatedDataObject; lastSchemaObject = relationship.RelatedSchemaObject; } } 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]; Schema.Field schemaField = schemaObject.GetField(field); schemaField.SetPrivateDataCallback(objectToSetValueOn, databaseValue); } } yield return(dataObject); } }
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); }