/// <summary> /// Función que carga la relacion ParentCategory desde la base de datos /// </summary> /// <param name="category">Padre: CategoryEntity</param> /// <exception cref="ArgumentNullException"> /// Si <paramref name="category"/> no es un <c>CategoryEntity</c>. /// </exception> public void LoadRelationParentCategory(CategoryEntity category, Dictionary <string, IEntity> scope) { if (category == null) { throw new ArgumentException("The argument can't be null"); } bool closeConnection = false; try { // Crea una nueva conexión si es necesario if (dbConnection == null || dbConnection.State.CompareTo(ConnectionState.Closed) == 0) { closeConnection = true; dbConnection = dataAccess.GetNewConnection(); dbConnection.Open(); } // Crea un nuevo command string cmdText = "SELECT idParentCategory FROM [Category] WHERE idCategory = @idCategory"; SqlCeCommand sqlCommand = dataAccess.GetNewCommand(cmdText, dbConnection, dbTransaction); SqlCeParameter parameter = dataAccess.GetNewDataParameter("@idCategory", DbType.Int32); // Establece los valores a los parametros del command parameter.Value = category.Id; sqlCommand.Parameters.Add(parameter); // Execute commands object idRelation = sqlCommand.ExecuteScalar(); if (idRelation != null && ((int)idRelation) > 0) { // Create data access objects and set connection objects CategoryDataAccess categoryDataAccess = new CategoryDataAccess(); categoryDataAccess.SetConnectionObjects(dbConnection, dbTransaction); // Carga los objetos relacionados category.ParentCategory = categoryDataAccess.Load(((int)idRelation), true, scope); } } catch (DbException dbException) { // Relanza una excepcion personalizada throw new UtnEmallDataAccessException(dbException.Message, dbException); } finally { // Cierra la conexión si fue inicializada if (closeConnection) { dbConnection.Close(); } } }
/// <summary> /// Función para eliminar una lista de entidades relacionadas desde la base de datos /// </summary> /// <param name="collectionDataAccess">IDataAccess de la relacion</param> /// <param name="collection">La colección de entidades a eliminar</param> /// <param name="scope">Estructura interna para evitar problemas de referencia circular</param> /// <returns>True si la colección no es nula</returns> private bool DeleteCategoryCollection(CategoryDataAccess collectionDataAccess, Collection <CategoryEntity> collection, Dictionary <string, IEntity> scope) { if (collection == null) { return(false); } // Establece los objetos de conexión al data access de la relación. collectionDataAccess.SetConnectionObjects(dbConnection, dbTransaction); // Elimina los objetos relacionados for (int i = 0; i < collection.Count; i++) { collectionDataAccess.Delete(collection[i], scope); } return(true); }
/// <summary> /// Función que carga la relacion Childs desde la base de datos /// </summary> /// <param name="category">Entidad padre CategoryEntity</param> /// <param name="scope">Estructura de datos interna para evitar los problemas de referencia circular</param> /// <exception cref="ArgumentNullException"> /// Si <paramref name="category"/> no es un <c>CategoryEntity</c>. /// </exception> public void LoadRelationChilds(CategoryEntity category, Dictionary <string, IEntity> scope) { if (category == null) { throw new ArgumentException("The argument can't be null"); } // Crea un objeto data access para los objetos relacionados CategoryDataAccess categoryDataAccess = new CategoryDataAccess(); // Establece los objetos de la conexión al data access de la relacion categoryDataAccess.SetConnectionObjects(dbConnection, dbTransaction); // Carga los objetos relacionadoss category.Childs = categoryDataAccess.LoadByCategoryCollection(category.Id, scope); }
/// <summary> /// Actualiza la base de datos para reflejar el estado actual de la lista. /// </summary> /// <param name="collectionDataAccess">El IDataAccess de la relación</param> /// <param name="parent">El objeto padre</param> /// <param name="collection">una colección de items</param> /// <param name="isNewParent">Si el padre es un objeto nuevo</param> /// <param name="scope">Estructura de datos interna para evitar problemas de referencia circular</param> /// <exception cref="UtnEmallDataAccessException"> /// Si una DbException ocurre cuando se accede a la base de datos /// </exception> private void SaveCategoryCollection(CategoryDataAccess collectionDataAccess, CategoryEntity parent, Collection <CategoryEntity> collection, bool isNewParent, Dictionary <string, IEntity> scope) { if (collection == null) { return; } // Establece los objetos de conexión collectionDataAccess.SetConnectionObjects(dbConnection, dbTransaction); // Establece la relación padre/hijo for (int i = 0; i < collection.Count; i++) { bool changed = collection[i].Changed; collection[i].ParentCategory = parent; collection[i].Changed = changed; } // Si el padre es nuevo guarda todos los hijos, sino controla las diferencias con la base de datos. if (isNewParent) { for (int i = 0; i < collection.Count; i++) { collectionDataAccess.Save(collection[i], scope); } } else { // Controla los hijos que ya no son parte de la relación string idList = "0"; if (collection.Count > 0) { idList = "" + collection[0].Id; } for (int i = 1; i < collection.Count; i++) { idList += ", " + collection[i].Id; } // Retorna los ids que ya no existe en la colección actual string command = "SELECT idCategory FROM [Category] WHERE idParentCategory = @idParentCategory AND idCategory NOT IN (" + idList + ")"; SqlCeCommand sqlCommand = dataAccess.GetNewCommand(command, dbConnection, dbTransaction); SqlCeParameter sqlParameterId = dataAccess.GetNewDataParameter("@idParentCategory", DbType.Int32); sqlParameterId.Value = parent.Id; sqlCommand.Parameters.Add(sqlParameterId); IDataReader reader = sqlCommand.ExecuteReader(); Collection <CategoryEntity> objectsToDelete = new Collection <CategoryEntity>(); // Inserta los id en una lista List <int> listId = new List <int>(); while (reader.Read()) { listId.Add(reader.GetInt32(0)); } reader.Close(); // Carga los items a ser eliminados foreach (int id in listId) { CategoryEntity entityToDelete = collectionDataAccess.Load(id, scope); objectsToDelete.Add(entityToDelete); } // Esto se realiza porque el reader debe ser cerrado despues de eliminar las entidades for (int i = 0; i < objectsToDelete.Count; i++) { collectionDataAccess.Delete(objectsToDelete[i], scope); } System.DateTime timestamp; // Controla todas las propiedades de los items de la colección // para verificar si alguno cambio for (int i = 0; i < collection.Count; i++) { CategoryEntity item = collection[i]; if (!item.Changed && !item.IsNew) { // Crea el command string sql = "SELECT timestamp FROM [Category] WHERE idCategory = @idCategory"; SqlCeCommand sqlCommandTimestamp = dataAccess.GetNewCommand(sql, dbConnection, dbTransaction); // Establece los datos a los parametros del command SqlCeParameter sqlParameterIdPreference = dataAccess.GetNewDataParameter("@idCategory", DbType.Int32); sqlParameterIdPreference.Value = item.Id; sqlCommandTimestamp.Parameters.Add(sqlParameterIdPreference); timestamp = ((System.DateTime)sqlCommandTimestamp.ExecuteScalar()); if (item.Timestamp != timestamp) { item.Changed = true; } } // Guarda el item si cambio o es nuevo if (item.Changed || item.IsNew) { collectionDataAccess.Save(item); } } } }
/// <summary> /// Función que guarda un PreferenceEntity en la base de datos. /// </summary> /// <param name="preference">PreferenceEntity a guardar</param> /// <param name="scope">Estructura interna para evitar problemas con referencias circulares</param> /// <exception cref="ArgumentNullException"> /// Si <paramref name="preference"/> no es un <c>PreferenceEntity</c>. /// </exception> /// <exception cref="UtnEmallDataAccessException"> /// Si una DbException ocurre cuando se accede a la base de datos /// </exception> public void Save(PreferenceEntity preference, Dictionary <string, IEntity> scope) { if (preference == null) { throw new ArgumentException("The argument can't be null"); } // Crear una clave unica para identificar el objeto dentro del scope interno string scopeKey = preference.Id.ToString(NumberFormatInfo.InvariantInfo) + "Preference"; if (scope != null) { // Si se encuentra dentro del scope lo retornamos if (scope.ContainsKey(scopeKey)) { return; } } else { // Crea un nuevo scope si este no fue enviado scope = new Dictionary <string, IEntity>(); } try { // Crea una nueva conexion y una nueva transaccion si no hay una a nivel superior if (!isGlobalTransaction) { dbConnection = dataAccess.GetNewConnection(); dbConnection.Open(); dbTransaction = dbConnection.BeginTransaction(); } string commandName = ""; bool isUpdate = false; // Verifica si se debe hacer una actualización o una inserción if (preference.IsNew || !DataAccessConnection.ExistsEntity(preference.Id, "Preference", "idPreference", dbConnection, dbTransaction)) { commandName = "INSERT INTO [Preference] (idPreference, ACTIVE, LEVEL, IDCUSTOMER, IDCATEGORY, [TIMESTAMP] ) VALUES( @idPreference, @active,@level,@idCustomer,@idCategory, GETDATE()); "; } else { isUpdate = true; commandName = "UPDATE [Preference] SET active = @active, level = @level, idCustomer = @idCustomer, idCategory = @idCategory , timestamp=GETDATE() WHERE idPreference = @idPreference"; } // Se crea un command SqlCeCommand sqlCommand = dataAccess.GetNewCommand(commandName, dbConnection, dbTransaction); // Agregar los parametros del command . SqlCeParameter parameter; if (!isUpdate && preference.Id == 0) { preference.Id = DataAccessConnection.GetNextId("idPreference", "Preference", dbConnection, dbTransaction); } parameter = dataAccess.GetNewDataParameter("@idPreference", DbType.Int32); parameter.Value = preference.Id; sqlCommand.Parameters.Add(parameter); FillSaveParameters(preference, sqlCommand); // Ejecutar el command sqlCommand.ExecuteNonQuery(); scopeKey = preference.Id.ToString(NumberFormatInfo.InvariantInfo) + "Preference"; // Agregar la entidad al scope actual scope.Add(scopeKey, preference); // Guarda las colecciones de objetos relacionados. // Guardar objetos relacionados con la entidad actual if (preference.Category != null) { CategoryDataAccess categoryDataAccess = new CategoryDataAccess(); categoryDataAccess.SetConnectionObjects(dbConnection, dbTransaction); categoryDataAccess.Save(preference.Category, scope); } // Actualizar Update(preference); // Cierra la conexión si fue abierta en la función if (!isGlobalTransaction) { dbTransaction.Commit(); } // Actualizar los campos new y changed preference.IsNew = false; preference.Changed = false; } catch (DbException dbException) { // Anula la transaccion if (!isGlobalTransaction) { dbTransaction.Rollback(); } // Relanza una excepcion personalizada throw new UtnEmallDataAccessException(dbException.Message, dbException); } finally { // Cierra la conexión si fue inicializada if (!isGlobalTransaction) { dbConnection.Close(); dbConnection = null; dbTransaction = null; } } }