Beispiel #1
0
        public bool IsFieldDirty(string fieldName)
        {
            Schema.Field field = GetField(fieldName);

            object currentValue = field.GetValue(this);
            object dirtyValue   = GetDirtyValue(fieldName);

            if (currentValue == null && dirtyValue == null)
            {
                return(false);
            }

            return(currentValue == null ? !dirtyValue.Equals(currentValue) : !currentValue.Equals(dirtyValue));
        }
Beispiel #2
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);
        }
Beispiel #3
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);
            }
        }
Beispiel #4
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);
        }