7
Good morning,
I am having difficulty updating a record with entityframework, I will inform the whole structure below. In short, I have a register of artists, where these artists are related to address and categories.
An artist can have an address (one for one), and artists can have many categories (many for many).
entities:
Artist: relationship one to one with address many relationship to many with categories
public class Artista
{
public Artista()
{
ArtistaCategoria = new List<ArtistaCategoria>();
}
public int ArtistaId { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public string Site { get; set; }
public string Descricao { get; set; }
public virtual Endereco Endereco { get; set; }
public DateTime DataCadastro { get; set; }
public DateTime DataAtualizacao { get; set; }
public virtual ICollection<ArtistaCategoria> ArtistaCategoria { get; set; }
}
public class Categoria
{
public Categoria()
{
}
public int CategoriaId { get; set; }
public string Nome { get; set; }
public virtual ICollection<ArtistaCategoria> ArtistaCategoria { get; set; }
}
public class Endereco
{
public Endereco()
{
Municipio = new Municipio();
}
public int EnderecoId { get; set; }
public string Logradouro { get; set; }
public string Numero { get; set; }
public string Bairro { get; set; }
public string Cep { get; set; }
public int MunicipioId { get; set; }
public virtual Municipio Municipio { get; set; }
}
public class Municipio
{
public Municipio()
{
}
public int MunicipioId { get; set; }
public string Nome { get; set; }
public string Cep { get; set; }
}
Configuration Fluent API
public class ArtistaConfiguration : EntityTypeConfiguration<Artista>
{
public ArtistaConfiguration()
{
HasKey(a => a.ArtistaId);
Property(a => a.Nome)
.IsRequired();
Property(a => a.Email)
.HasMaxLength(150);
}
public class EnderecoConfiguration : EntityTypeConfiguration<Endereco>
{
public EnderecoConfiguration()
{
HasKey(x => x.EnderecoId);
Property(x => x.Logradouro).IsRequired();
HasRequired(m => m.Municipio)
.WithMany()
.HasForeignKey(m => m.MunicipioId);
Property(m => m.Cep)
.IsFixedLength()
.HasMaxLength(9)
.HasColumnType("char");
}
}
I am unable to edit the data, when I save the categories, an error is shown stating that Municipioid is invalid.
I’ve always worked with ADO and Stored Procedures, and I’ve always heard a lot of people say that this is a drag, that with Entity it’s much faster and easier, but honestly I think I lost control, with Sps you have the application in hand, any mistake is easy to identify.
In this case, when editing the relationship of the category and the artist, an error is generated in the municipality (artist > address > municipality), I honestly cannot identify the problem.
Follow the update code:
public void Update(Artista obj, string[] arrayCategoria)
{
AtualizaEndereco(obj);
ValidaCategorias(obj, arrayCategoria);
Db.Entry(obj).State = EntityState.Modified;
Db.SaveChanges();
}
private void AtualizaEndereco(Artista artista)
{
var endereco = artista.Endereco;
endereco.Municipio = null;
Db.Entry(endereco).State = EntityState.Modified;
}
private void AtualizarCategorias(Artista artista, string[] categorias)
{
var artistaAtual = Db.Artistas
.FirstOrDefault(a => a.ArtistaId == artista.ArtistaId);
//todo: fazer lista de categoria de acordo com array recebido
List<Categoria> categoriasSelecionadas = new List<Categoria>();
if (categorias != null)
{
foreach (var cat in categorias)
{
categoriasSelecionadas.Add(Db.Categorias.Find(int.Parse(cat)));
}
}
foreach (var categoria in categoriasSelecionadas)
{
var artistaCategoria = new ArtistaCategoria
{
Artista = artistaAtual,
Categoria = categoria
};
Db.ArtistaCategoria.Add(artistaCategoria);
Db.SaveChanges();
}
}
Controller code that edits the register:
public class ArtistaController : Controller
{
private readonly IArtistaAppService _artistaApp;
private readonly IMunicipioAppService _municipioApp;
private readonly ICategoriaAppService _categoriaApp;
public ArtistaController(IArtistaAppService artistaApp, IMunicipioAppService municipioApp, ICategoriaAppService categoriaApp)
{
_artistaApp = artistaApp;
_municipioApp = municipioApp;
_categoriaApp = categoriaApp;
}
[...]
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(ArtistaViewModel artista, string[] arrayCategoria)
{
if (ModelState.IsValid)
{
var artistaDomain = Mapper.Map<ArtistaViewModel, Artista>(artista);
_artistaApp.Update(artistaDomain, arrayCategoria);
return RedirectToAction("index");
}
return View(artista);
}
@model ViewModels.ArtistaViewModel
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default" data-collapsed="0">
<div class="panel-heading">
<div class="panel-title">
Dados do cadastro<br />
</div>
<div class="panel-options">
<a href="#" data-rel="collapse"><i class="entypo-down-open"></i></a>
</div>
</div>
<div class="panel-body">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.ArtistaId)
<div class="form-group">
@Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-blue btn-icon" type="button" id='addButton'>Adicionar telefone<i class="entypo-phone"></i></button>
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Endereco.Cep, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-5">
@Html.EditorFor(model => model.Endereco.Cep, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Endereco.Logradouro, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-5">
@Html.EditorFor(model => model.Endereco.Logradouro, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Endereco.Numero, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-5">
@Html.EditorFor(model => model.Endereco.Numero, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Endereco.Bairro, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-5">
@Html.EditorFor(model => model.Endereco.Bairro, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Endereco.MunicipioId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-5">
<select id="Endereco_MunicipioId" name="Endereco.MunicipioId" class="form-control"></select>
</div>
</div>
@Html.HiddenFor(model => model.Endereco.EnderecoId)
@{
List<ViewModels.CategoriasSelecionadas> categorias = ViewBag.Categorias;
foreach (var categoria in categorias)
{
<input type="checkbox"
name="arrayCategoria"
value="@categoria.CategoriaId"
@(Html.Raw(categoria.Selecionada ? "checked=\"checked\"" : "")) />
@categoria.CategoriaId @: @categoria.Nome
}
}
</div>
</div>
</div>
</div>
</div>
<div class="form-group default-padding">
<button class="btn btn-success btn-icon" type="submit">Salvar<i class="entypo-check"></i></button>
<button type="reset" class="btn btn-icon btn-default">Cancelar alterações <i class="entypo-cancel"></i></button>
<a href="@Url.Action("Index")" class="btn btn-icon btn-info">Voltar para listagem<i class="entypo-reply"></i></a>
</div>
}
Possible duplicate of Update Many to Many Entity Framework c#
– Marco Souza
Again the same questions ?
– Marco Souza
In fact they are similar, one was created on the basis of the answers given by the Roma, to continue the reasoning, I repeated the question applying the indicated amendments...
– Alexandre Previatti