Ejemplo n.º 1
0
        /// <summary>
        /// Salva o registro na base de dados
        /// </summary>
        /// <param name="model"></param>
        public static IID Save(IBaseModel model)
        {
            IID         result      = null;
            bool        oldNew      = model.New;
            IID         fk          = null;
            ForeignKeys foreignKeys = new ForeignKeys();
            bool        inserting   = false;
            IEnumerable <MyHierarchicalType> models          = null;
            TableDefinitionAttribute         tableDefinition = null;

            try
            {
                //se este model for do tipo IChildModel
                //deve-se usar a conexão do Parent e cria uma foreignKey
                if (model.IsChildModel())
                {
                    dynamic m = model;

                    if (m.Parent != null)
                    {
                        model.Connection = m.Parent.Connection;

                        models = Utilities.DbUtils.GetModels(m.Parent as IBaseModel);

                        foreach (var modelType in models)
                        {
                            if (modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false).Count() > 0)
                            {
                                tableDefinition = modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false)[0] as TableDefinitionAttribute;

                                fk = Utilities.DbUtils.GetPrimaryKeyValue(m);

                                //adicionar o foreign key, se necessário usar no command
                                foreignKeys.Add(tableDefinition.TableName, fk);
                            }
                        }
                    }
                }

                model.Connection.Open();
                model.Connection.BeginTransaction();

                //Detectar se é uma inserção
                //se o modelo é marcado como não atualizável, deverá sempre sofrer insert
                object[] notUpdatable = model.GetType().GetCustomAttributes(typeof(NotUpdatableAttribute), true);

                inserting = notUpdatable.Count() > 0 || model.New;

                //Validar
                model.Validate(!inserting);
                model.BeforeSave(!inserting);

                //revalidar o insert, pois pode ter sido modificado pelo Validate e BeforeSave
                inserting = notUpdatable.Count() > 0 || model.New;

                models = Utilities.DbUtils.GetModels(model);

                //para todos os modelos retornados, iremos buscar as tabelas que compoe estes modelos
                foreach (var modelType in models.OrderByDescending(o => o.Order))
                {
                    if (modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false).Count() > 0)
                    {
                        tableDefinition = modelType.Type.GetCustomAttributes(typeof(TableDefinitionAttribute), false)[0] as TableDefinitionAttribute;

                        CommandFactory cf = new CommandFactory(model.Connection,
                                                               model.Connection.Transaction,
                                                               modelType.Type, model, foreignKeys);

                        using (Command command = cf.CreateCommand(inserting))
                        {
                            //Preparar o comando antes de executar
                            model.PrepareCommand(command, !inserting);

                            //executar o comando
                            command.ExecuteNonQuery();

                            //se esta tabela possuir GUID, deverá ser armazenada para referência como chave estrangeira
                            if (Utilities.DbUtils.Tables[tableDefinition.TableName].Fields.Contains(tableDefinition.PrimaryKey))
                            {
                                fk = Utilities.DbUtils.GetPrimaryKeyValue(model);
                            }

                            if (!result.IsValid())
                            {
                                result = fk;
                            }

                            //adicionar o foreign key, se necessário usar no command
                            foreignKeys.Add(tableDefinition.TableName, fk);
                        }
                    }
                }

                model.AfterSave(!inserting);
                model.Connection.CommitTransaction();
                model.New = false;
            }
            catch
            {
                model.Connection.RollbackTransaction();
                model.New = oldNew;
                throw;
            }
            finally
            {
                model.Connection.Close();
            }

            model.New = false;
            return(result);
        }