Is it safe to save multiple entities at the same time in the ASP.NET MVC Controller?

7

I need to save 12 entities to the same method in Controller , I do not know if I'm doing it right.

In my method Create of Controller , I call all entities and add all attributes in the same View . When you click the save button, you are saving normally. I wonder if this is the correct form? If it is not, I'd like to know which one is best.

Remembering that this is just a simple application, where it will not contain much information. It will only be used so you do not need to scan new forms.

My Action:

public ActionResult Create()
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Animal animal, Atividade atividade, Comunicacao comunicacao, Educacao educacao,
     Especie especie, EstruturaPropriedade estruturaPropriedade, Informacao informacao, Poco poco, ProdutorRural produtorRural,
    Propriedade propriedade, Questionario questionario, Saude saude)
{
    if (ModelState.IsValid)
    {
        db.Animais.Add(animal);
        db.Atividades.Add(atividade);
        db.Comunicacoes.Add(comunicacao);
        db.Educacoes.Add(educacao);
        db.Especies.Add(especie);
        db.EstruturaPropriedades.Add(estruturaPropriedade);
        db.Infomacoes.Add(informacao);
        db.Pocos.Add(poco);
        db.ProdutorRurals.Add(produtorRural);   
        db.Propriedades.Add(propriedade);
        db.Questionarios.Add(questionario);
        db.Saudes.Add(saude);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(propriedade);
}

And in View , I call the attributes through the foreign key . I will not post all the code, because they are 213 attributes, and would be difficult to understand, by the size of the code, but I will put a part.

Entity:

public class Propriedade
    {
        [Key]
        public int iPropriedadeID { set; get; }
        [Required(ErrorMessage = "Digite o nome do Proprietário")]
        public string sProprietario { get; set; }
        public string sSexo { get; set; }
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
        public DateTime? dtNasc { get; set; }
        public string sTelefone { get; set; }
        public string sCelular { get; set; }
        public string sEndereco { get; set; }
        public int? iRg { get; set; }
        public string sUfrg { get; set; }
        public string sCpf { get; set; }
        public string sCpts { get; set; }
        public string sSerieCtps { get; set; }
        public string sNomePropriedade { get; set; }
        public int? iInscricaoMunicipal { get; set; }
        public bool bRegPropriedade { get; set; }
        public string sCartorio { get; set; }
        public string sMtricula { get; set; }
        public string sLivro { get; set; }
        public int? iArea { get; set; }
        public int? iAreaRegistrada { get; set; }
        public int? iAreaTotal { get; set; }
        public bool bIncra { get; set; }
        public string sNumIncra { get; set; }
        public string sNirf { get; set; }
        public string sInscricaoImobiliaria { get; set; }
        public string sDistrito { get; set; }
        public int? iTempoOcupacao { get; set; }
        public string sLocalX { get; set; }
        public string sLocalY { get; set; }

        public virtual ProdutorRural ProdutorRural { get; set; }
        public virtual Animal Animal{ get; set; }
        public virtual Atividade Atividade { get; set; }
        public virtual EstruturaPropriedade EstruturaPropriedade  { get; set; }

The View to save has 2300 rows, so I'll post the beginning, and I follow this base table until the end:

<div class="row">
            <div class="col-md-2">
                Nome do Proprietário:
            </div>
            <div class="col-md-10">
                @Html.TextBoxFor(model => model.sProprietario, new {@class = "form-control", style = "width:5000px", placeholder = "Nome Completo"})
            </div>
        </div>
        <hr>
        @*-------------------------------------------------------LINHA 2-----------------------------------------------------------------------------*@

        <div class="row">
            <div class="col-md-2">
                Sexo:
            </div>
            <div class="col-md-3">
                @Html.DropDownListFor(model => model.sSexo, new SelectList(
                    new[]
                    {
                        new {Value = "Masculino", Text = "Masculino"},
                        new {Value = "Feminino", Text = "Feminino"},
                    },
                    "Value",
                    "Text"
                    ), new {@class = "form-control", style = "width: 150px;"})
            </div>
            <div class="col-md-2">
                Data de Nascimento:
            </div>
            <div class="col-md-5">
                @Html.EditorFor(model => model.dtNasc, new { placeholder = "Ex: 20/02/2014"})
                @Html.ValidationMessageFor(model => model.dtNasc)
            </div>
        </div>
        <hr>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Salvar" class="btn btn-default"/>
            </div>
        </div>
    
asked by anonymous 26.01.2015 / 20:35

1 answer

10

I will base my answer by not mentioning a correct way, but rather a performative way of doing this.

I see this with severe concern:

public ActionResult Create(Animal animal, Atividade atividade, Comunicacao comunicacao, Educacao educacao,
     Especie especie, EstruturaPropriedade estruturaPropriedade, Informacao informacao, Poco poco, ProdutorRural produtorRural,
    Propriedade propriedade, Questionario questionario, Saude saude) { ... }

Not that it's wrong, but this makes maintenance absurdly difficult, since the programmer is going to have to find out how the complete binding of the form works.

The performative way of doing this is by specifying a ViewModel that contains all the properties that are entities:

public class FormularioViewModel 
{
    public Animal Animal { get; set; }
    public Atividade Atividade { get; set; }
    public Comunicacao Comunicacao { get; set; }
    public Educacao Educacao { get; set; }
    public Especie Especie { get; set; }
    public EstruturaPropriedade EstruturaPropriedade { get; set; }
    public Informacao Informacao { get; set; }
    public Poco Poco { get; set; }
    public ProdutorRural ProdutorRural { get; set; }
    public Propriedade Propriedade { get; set; }
    public Questionario Questionario { get; set; }
    public Saude Saude { get; set; }
}

ViewModels are not persisted. They are only anemic classes used to organize and validate your form. ViewModels , when you implement IValidatableObject , behave identically to a Model , including updating the Controller %.

The Action header of your Controller

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FormularioViewModel viewModel) { ... }

And View :

    <div class="row">
        <div class="col-md-2">
            Nome do Proprietário:
        </div>
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.Animal.Proprietario, new {@class = "form-control", style = "width:5000px", placeholder = "Nome Completo"})
        </div>
    </div>
    <hr>
    @*-------------------------------------------------------LINHA 2-----------------------------------------------------------------------------*@

    <div class="row">
        <div class="col-md-2">
            Sexo:
        </div>
        <div class="col-md-3">
            @Html.DropDownListFor(model => model.Animal.Sexo, new SelectList(
                new[]
                {
                    new {Value = "Masculino", Text = "Masculino"},
                    new {Value = "Feminino", Text = "Feminino"},
                },
                "Value",
                "Text"
                ), new {@class = "form-control", style = "width: 150px;"})
        </div>
        <div class="col-md-2">
            Data de Nascimento:
        </div>
        <div class="col-md-5">
            @Html.EditorFor(model => model.Animal.DataNascimento, new { placeholder = "Ex: 20/02/2014"})
            @Html.ValidationMessageFor(model => model.Animal.DataNascimento)
        </div>
    </div>
    <hr>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Salvar" class="btn btn-default"/>
        </div>
    </div>

Action to persist data would look like this:

if (ModelState.IsValid)
{
    db.Animais.Add(viewModel.Animal);
    db.Atividades.Add(viewModel.Atividade);
    db.Comunicacoes.Add(viewModel.Comunicacao);
    db.Educacoes.Add(viewModel.Educacao);
    db.Especies.Add(viewModel.Especie);
    db.EstruturaPropriedades.Add(viewModel.EstruturaPropriedade);
    db.Infomacoes.Add(viewModel.Informacao);
    db.Pocos.Add(viewModel.Poco);
    db.ProdutorRurals.Add(viewModel.ProdutorRural);   
    db.Propriedades.Add(viewModel.Propriedade);
    db.Questionarios.Add(viewModel.Questionario);
    db.Saudes.Add(viewModel.Saude);

    db.SaveChanges();
    return RedirectToAction("Index");
}

return View(propriedade);

In addition, using this approach, you can segment your View into Partials , more or less like this:

@Html.Partial("_Animal", Model.Animal)
@Html.Partial("_Atividade", Model.Atividade)
@Html.Partial("_Comunicacao", Model.Comunicacao)
...

So it would not have 2300 lines.

    
26.01.2015 / 22:03