Exemplo n.º 1
0
        // Uses annotations to provide a generic read function to all proper DataObjects
        protected void GenericRead(IDataObject targetObject)
        {
            if (targetObject == null)
            {
                throw new ArgumentNullException("targetObject");
            }

            SqlBackedClassAttribute dataManagementAttribute = (SqlBackedClassAttribute)Attribute.GetCustomAttribute(targetObject.GetType(), typeof(SqlBackedClassAttribute));

            if (dataManagementAttribute == null)
            {
                throw new ArgumentException("The given object does not have the required SqlBackedClassAttribute.");
            }

            // TODO this is ugly
            ProcedureParameter idParameter = default(ProcedureParameter);

            GetFieldsAndProperties(targetObject.GetType(), (field, getter) =>
            {
                if (idParameter.Name != null)
                {
                    // No need to search further
                    return;
                }

                StoredDataAttribute sqlFieldAttribute = (StoredDataAttribute)Attribute.GetCustomAttribute(field, typeof(StoredDataAttribute));
                if (sqlFieldAttribute == null || Attribute.GetCustomAttribute(field, typeof(PrimaryKeyAttribute)) == null)
                {
                    return;
                }

                // Found the ID column
                idParameter = new ProcedureParameter(sqlFieldAttribute.StoredName ?? field.Name, targetObject.ID);
            });

            // Run the actual update
            DataTable results = _database.RunProcedure(dataManagementAttribute.GetByIdProcedureName, idParameter);

            if (results.Rows.Count == 0)
            {
                throw new IDNotFoundException("The given ID does not correspond to a record.");
            }
            else if (results.Rows.Count > 1)
            {
                throw new System.Data.DuplicateNameException("The given ID is ambiguous.");
            }

            // Update the data in the object
            InitializeData(targetObject, results.Rows[0]);
        }
Exemplo n.º 2
0
        // Uses annotations to provide a generic update function to all proper DataObjects
        protected void GenericUpdate(IDataObject targetObject)
        {
            if (targetObject == null)
            {
                throw new ArgumentNullException("targetObject");
            }

            if (!targetObject.IsStoredData)
            {
                // Object does not already exist in SQL
                throw new ArgumentException("The given object is not SQL backed; that is, it does not exist in SQL yet.");
            }

            SqlBackedClassAttribute dataManagementAttribute = (SqlBackedClassAttribute)Attribute.GetCustomAttribute(targetObject.GetType(), typeof(SqlBackedClassAttribute));

            if (dataManagementAttribute == null)
            {
                throw new ArgumentException("The given object does not have the required SqlBackedClassAttribute.");
            }

            List <ProcedureParameter> parameters = new List <ProcedureParameter>();

            GetFieldsAndProperties(targetObject.GetType(), (field, getter) =>
            {
                StoredDataAttribute sqlFieldAttribute = (StoredDataAttribute)Attribute.GetCustomAttribute(field, typeof(StoredDataAttribute));
                if (sqlFieldAttribute == null)
                {
                    // Continue
                    return;
                }

                // Don't write read-only properties
                if (field.GetCustomAttribute <DataPropertyAttribute>() != null)
                {
                    // Continue
                    return;
                }

                ProcedureParameter param = new ProcedureParameter(sqlFieldAttribute.StoredName ?? field.Name, getter(targetObject) ?? DBNull.Value);
                //if (sqlFieldAttribute.DataType.HasValue)
                //{
                //    // If the data type is manually specified
                //    param.DbType = sqlFieldAttribute.DataType.Value;
                //}
                parameters.Add(param);
            });

            // Run the actual update
            _database.RunNonQueryProcedure(dataManagementAttribute.UpdateProcedureName, parameters.ToArray());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Modifies the given object to match the data given in the specified DataRow.
        /// </summary>
        public static void InitializeData(IDataObject targetObject, DataRow data)
        {
            SqlBackedClassAttribute dataManagementAttribute = (SqlBackedClassAttribute)Attribute.GetCustomAttribute(targetObject.GetType(), typeof(SqlBackedClassAttribute));

            if (dataManagementAttribute == null)
            {
                throw new ArgumentException("The given object does not have the required SqlBackedClassAttribute.");
            }

            SetFieldsAndProperties(targetObject.GetType(), (field, setter) =>
            {
                StoredDataAttribute sqlFieldAttribute = null;
                if ((sqlFieldAttribute = Attribute.GetCustomAttribute(field, typeof(StoredDataAttribute)) as StoredDataAttribute) == null)
                {
                    return;
                }


                // Found a SQL column
                object dataInstance = data[sqlFieldAttribute.StoredName ?? field.Name];

                ForeignKeyAttribute fkey = null;
                if ((fkey = Attribute.GetCustomAttribute(field, typeof(ForeignKeyAttribute)) as ForeignKeyAttribute) != null && fkey.ForeignType == GetMemberType(field))
                {
                    // Get the object by ID and use that to set the field
                    // We have to use reflection to invoke a generic method with a type only known at runtime
                    // TODO strongly type the method names

                    throw new NotSupportedException("The static InitializeData method does not support object-type foreign keys.");
                    //field.SetValue(targetObject, this.GetType().GetMethod("GetObjectByID").MakeGenericMethod(fkey.ForeignType).Invoke(this, new object[]{dataInstance}));
                }
                else
                {
                    // Set the field directly
                    setter(targetObject, dataInstance is DBNull ? null : dataInstance);
                }
            });

            SetObjectInternals(targetObject, targetObject.ID, true);
        }
Exemplo n.º 4
0
        public void SaveObject(IDataObject target)
        {
            SqlBackedClassAttribute dataAttr = Attribute.GetCustomAttribute(target.GetType(), typeof(SqlBackedClassAttribute)) as SqlBackedClassAttribute;

            if (dataAttr == null)
            {
                throw new InvalidOperationException("SqlBackedClassAttribute not found on the type of the given object.");
            }

            if (dataAttr.InsertProcedureName == null && dataAttr.UpdateProcedureName == null)
            {
                throw new ReadOnlyException("The given object type is read only.");
            }

            if (target.IsStoredData)
            {
                GenericUpdate(target);
            }
            else
            {
                GenericInsert(target);
            }
        }
Exemplo n.º 5
0
        // Uses annotations to provide a generic insert function to all proper DataObjects
        protected void GenericInsert(IDataObject targetObject)
        {
            if (targetObject == null)
            {
                throw new ArgumentNullException("targetObject");
            }

            SqlBackedClassAttribute dataManagementAttribute = (SqlBackedClassAttribute)Attribute.GetCustomAttribute(targetObject.GetType(), typeof(SqlBackedClassAttribute));

            if (dataManagementAttribute == null)
            {
                throw new ArgumentException("The given object does not have the required SqlBackedClassAttribute.");
            }

            List <ProcedureParameter> parameters = new List <ProcedureParameter>();

            string idColumnName = null;

            GetFieldsAndProperties(targetObject.GetType(), (field, getter) =>
            {
                StoredDataAttribute sqlFieldAttribute = (StoredDataAttribute)Attribute.GetCustomAttribute(field, typeof(StoredDataAttribute));
                if (sqlFieldAttribute == null)
                {
                    // Continue
                    return;
                }

                if (field.GetCustomAttribute <DataPropertyAttribute>() != null)
                {
                    // Continue
                    return;
                }

                if (Attribute.GetCustomAttribute(field, typeof(PrimaryKeyAttribute)) != null)
                {
                    // Set ID and handle specially
                    idColumnName = sqlFieldAttribute.StoredName ?? field.Name;
                    return;
                }

                // Found a non-ID column
                ProcedureParameter param = new ProcedureParameter(sqlFieldAttribute.StoredName ?? field.Name, getter(targetObject) ?? DBNull.Value);
                //if (sqlFieldAttribute.DataType.HasValue)
                //{
                //    // If the data type is manually specified
                //    param.DbType = sqlFieldAttribute.DataType.Value;
                //}
                parameters.Add(param);
            });

            // Run the actual insert, returns the inserted record
            DataTable insertedRecords = _database.RunProcedure(dataManagementAttribute.InsertProcedureName, parameters.ToArray());

            if (insertedRecords.Rows.Count != 1)
            {
                throw new DataException(string.Format("{0} rows were inserted when only one should have been.", insertedRecords.Rows.Count));
            }

            DataRow insertedRecord = insertedRecords.Rows[0];

            if (idColumnName == null)
            {
                throw new ArgumentException("The specified object does not have an explicitly specified ID column.");
            }

            SetObjectInternals(targetObject, (int)insertedRecord[idColumnName], true);
        }