/// <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); }