예제 #1
0
        public override bool Evaluate(DataObject dataObject)
        {
            SchemaObject schemaObject = Schema.Schema.GetSchemaObject(dataObject.GetType());
            Field        schemaField  = schemaObject.GetField(field);

            return(schemaField.GetValue(dataObject) != null);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        //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);
            }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }