Save Object to another object’s controller

Asked

Viewed 63 times

2

I have a class Collaborator, and a class Addressee. the collaborator has an address. In my collaborator class I have a:

 public virtual Endereco Endereco { get; set; }
 [ForeignKey("Endereco")]
 public int? IdEndereco { get; set; }

This is my Create Contributor view:

 <div class="row form-group">
    <div class="col col-md-2">
       <label for="text-input" class="form-control-label">Rua:</label>
    </div>
    <div class="col-lg-10" ;>
        @Html.EditorFor(model => model.Endereco.EndRua, new { htmlAttributes = new { @class = "form-control-sm", style = "min-width:100%;", type = "text", id = "text-input", name = "text-input", placeholder = "Rua | Avenida" } })
        @Html.ValidationMessageFor(model => model.Endereco.EndRua, "", new { @class = "text-danger" })
        @*<input style="min-width:100%;" type="text" id="text-input" name="text-input" placeholder="Rua | Avenida" class="form-control-sm">*@
    </div>
 </div>

 <div class="row form-group ">
    <div class="col col-md-2">
       <label for="email-input" class=" form-control-label">Número:</label>
    </div>
    <div class="col-md-1">
       @Html.EditorFor(model => model.Endereco.EndNumero, new { htmlAttributes = new { @class = "form-control-sm", style = "width:59px;", type = "text", id = "text-input", name = "text-input", placeholder = "N°" } })
       @Html.ValidationMessageFor(model => model.Endereco.EndNumero, "", new { @class = "text-danger" })
       @*<input style="width:59px;" type="text" id="numero-input" name="nascimento-input" placeholder="Número" class="form-control-sm">*@
    </div>

    <div class="offset-md-2">
       <div class="col col-md-2">
          <label for="cpf-input" class=" form-control-label">Bairro:</label>
       </div>
       <div class="col-md-10">
          @Html.EditorFor(model => model.Endereco.EndBairro, new { htmlAttributes = new { @class = "form-control-sm", style = "margin-left:-2px; width:237px;", type = "email", id = "text-input", name = "text-input", placeholder = "Bairro" } })
          @Html.ValidationMessageFor(model => model.Endereco.EndBairro, "", new { @class = "text-danger" })
          @*<input style="margin-left:-2px; width:237px;" type="text" id="bairro-input" name="bairro-input" placeholder="Bairro" class="form-control-sm">*@
       </div>
    </div>
    </div>


    <div class="row form-group ">
       <div class="col col-md-2">
          <label for="complemento-input" class=" form-control-label">Complemento:</label>
       </div>
       <div class="col-md-1">
          @Html.EditorFor(model => model.Endereco.EndComplemento, new { htmlAttributes = new { @class = "form-control-sm", style = "width:270px;", type = "text", id = "text-input", name = "text-input", placeholder = "Complemento" } })
          @Html.ValidationMessageFor(model => model.Endereco.EndComplemento, "", new { @class = "text-danger" })
           @*<input style="width:270px;" type="text" id="complemento-input" name="complemento-input" placeholder="Complemento" class="form-control-sm">*@
       </div>

    <div class="offset-md-5" style="margin-left:261px;">
        <div class="col col-md-2">
           <label for="cpf-input" class=" form-control-label">CEP:</label>
        </div>
          <div class="col-md-10">
             @Html.EditorFor(model => model.Endereco.EndCep, new { htmlAttributes = new { @class = "form-control-sm", style = "width:90px;", type = "text", id = "text-input", name = "text-input", placeholder = "Cep" } })
             @Html.ValidationMessageFor(model => model.Endereco.EndCep, "", new { @class = "text-danger" })
             @*<input style="width:90px;" type="text" id="cep-input" name="cep-input" placeholder="Cep" class="form-control-sm">*@
          </div>
      </div>

My controller is like this:

 public ActionResult Create(CadastrarColaboradorViewModel colaborador)
 {
            if (!ModelState.IsValid)
            {
                Colaborador colab = new Colaborador();

                //Salva endereço do Colaborador
                using (var db = new Contexto())
                {

                    Endereco endereco = new Endereco
                    {

                        EndBairro = colaborador.Endereco.EndBairro,
                        EndCep = colaborador.Endereco.EndCep,
                        EndCidade = colaborador.Endereco.EndCidade,
                        EndComplemento = colaborador.Endereco.EndComplemento,
                        EndNumero = colaborador.Endereco.EndNumero,
                        EndRua = colaborador.Endereco.EndRua,
                        EndUf = colaborador.Endereco.EndUf
                    };
                    db.Endereco.Add(endereco);
                    db.SaveChanges();
                    var idEndereco = endereco.IdEndereco;
                    colab.IdEndereco = idEndereco;
                }
                //Salva Endereço Fim *-*-*-*

                colab.Nome = colaborador.Nome;
                colab.Cpf = colaborador.Cpf;
                colab.DataDeNascimento = colaborador.DataDeNascimento;
                colab.Email = colaborador.Email;
                colab.EstadoCivil = colaborador.EstadoCivil;
                colab.Funcao = colaborador.Funcao;
                colab.Sexo = colaborador.Sexo;
                colab.StatusDoColaborador = colaborador.StatusDoColaborador;
                colab.TipoDeColaborador = colaborador.TipoDeColaborador;




                db.ColaboradorDb.Add(colab);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(colaborador);
        }

The problem is as follows, as I am saving the address and assigning the saved id to the contributor, the address is saved correctly, however, in some cases of the error, when saving the contributor, then the address is saved without a contributor.

I would like to know if there is a method where I can validate if the contributor was saved successfully, and if not, I would like to delete the address I have already saved in the bank.

  • You can use a try{}catch(Exception e){} to capture and treat these errors...

  • Good afternoon. There is a tool called Transactionscope, where if there is an error in the application, it returns the steps. Note more in Transactionscope - Microsoft In your case I think it helps.

1 answer

1


It is important you check the reason of cases of error, because suddenly it is a simple problem, as a mandatory property that should have been filled for a given scenario, or a field filled with size larger than configured, for example etc.

The problem of Address being saved without a Contributor occurs because there are 2 transactions:

  • One saves the Address
  • Another saves the Collaborator

The situation may occur where one of them has successfully saved the error and the other. There is more than one way to solve this problem.

I believe using try/catch is not the best way: you could put a try{...}catch{...} in the first transaction and only carry out the second one if the first one works. But this solution is not ideal because, what to do in cases that the first of right but fair the second transaction go wrong? No more rollback from the first transaction.

Another solution is using Unitofwork (on the internet has several implementation examples), where your transactions will be coordinated and you will execute a command SaveChanges recording all operations once, if any goes wrong occurs rollback.

Another way can be using transactions like this:

public ActionResult Create(CadastrarColaboradorViewModel colaborador)
{
   if (ModelState.IsValid)
   {           
        try
        {
            Colaborador colab = new Colaborador();

            //Salva endereço do Colaborador
            using (var db = new Contexto())
            {
                // Cria o objeto para controlar a transação
                using (DbContextTransaction transaction = db.Database.BeginTransaction())
                {
                        Endereco endereco = new Endereco
                        {

                            EndBairro = colaborador.Endereco.EndBairro,
                            EndCep = colaborador.Endereco.EndCep,
                            EndCidade = colaborador.Endereco.EndCidade,
                            EndComplemento = colaborador.Endereco.EndComplemento,
                            EndNumero = colaborador.Endereco.EndNumero,
                            EndRua = colaborador.Endereco.EndRua,
                            EndUf = colaborador.Endereco.EndUf
                        };

                        db.Endereco.Add(endereco);
                        db.SaveChanges();

                        var idEndereco = endereco.IdEndereco;
                        colab.IdEndereco = idEndereco;

                        //Salva Endereço Fim *-*-*-*

                        colab.Nome = colaborador.Nome;
                        colab.Cpf = colaborador.Cpf;
                        colab.DataDeNascimento = colaborador.DataDeNascimento;
                        colab.Email = colaborador.Email;
                        colab.EstadoCivil = colaborador.EstadoCivil;
                        colab.Funcao = colaborador.Funcao;
                        colab.Sexo = colaborador.Sexo;
                        colab.StatusDoColaborador = colaborador.StatusDoColaborador;
                        colab.TipoDeColaborador = colaborador.TipoDeColaborador;    

                        db.ColaboradorDb.Add(colab);
                        db.SaveChanges();

                    // Só nessa linha tenta fazer commit das 2 transações
                    transaction.Commit();
                }

                return RedirectToAction("Index");       
            }
            catch (Exception ex)
            {
                // Porém, se der erro faz rollback
                transaction.Rollback(); 
                return View(colaborador);
            }
        }    
    }
    return View(colaborador);
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.