Insertion 1 for many is recording two records in the database

Asked

Viewed 124 times

0

I have the following classes: Usuario, Noticia, Bloco and Editoria.

I had a relationship One to Many between the tables Noticia and Editoria, Noticia and Bloco.

It works perfectly, by putting the same relationship between Noticia and Usuario when recording a news in the bank records together a new user identical to the one doing the operation!

Below is code of Classes and of Controller:

[Table("Editoria")]
public class Editoria
{
    [Key]
    public int EditoriaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public bool Status { get; set; }

    [IgnoreDataMember]
    public virtual ICollection<Noticia> Noticias { get; set; }
}

[Table("Bloco")]
public class Bloco
{
    [Key]
    public int BlocoId { get; set; }
    public string Nome { get; set; }
    public bool Status { get; set; }

    [IgnoreDataMember]
    public virtual ICollection<Noticia> Noticias { get; set; }
}

[Table("Usuario")]
public class User
{
    [Key]
    public int UserId { get; set; }

    [Required]
    public string Nome { get; set; }

    [Required]
    [Remote("UserNameExists", "Usuario")]
    public string Login { get; set; }

    public string Senha { get; set; }

    public string Email { get; set; }

    public string Rg { get; set; }

    public string Cpf { get; set; }

    [DataType(DataType.DateTime)]
    [Display(Name = "Data de Cadastro")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime DataCadastro { get; set; }

    public bool Status { get; set; }

    public bool IsVisible { get; set; }

    public virtual ICollection<Role> Roles { get; set; }

    public virtual ICollection<Noticia> Noticias { get; set; }
}

public class Noticia
{
    [Key]
    public int NoticiaId { get; set; }

    [Display(Name = "Título")]
    [DataType(DataType.MultilineText)]
    [Required(ErrorMessage = "O título da notícia e obrigatório!")]
    [StringLength(200, MinimumLength = 20, ErrorMessage = "O Título deve ter no máximo 200 e no mínimo 20 caractéres!")]
    public string Titulo { get; set; }

    [Display(Name = "Resumo")]
    [DataType(DataType.MultilineText)]
    [StringLength(180, MinimumLength = 20, ErrorMessage = "O Resumo deve ter no máximo 180 e no mínimo 20 caractéres!")]
    public string Resumo { get; set; }

    [Display(Name = "Chapéu")]
    [StringLength(30, MinimumLength = 5, ErrorMessage = "O Chapéu deve ter no máximo 30 e no mínimo 5 caractéres!")]
    public string Chapeu { get; set; }

    [Display(Name = "Foto de capa")]
    public string UrlFotoCapa { get; set; }

    [Display(Name = "Conteúdo da Notícia")]
    [Required(ErrorMessage = "O conteúdo da notícia e obrigatório!")]
    public string Texto { get; set; }

    [DataType(DataType.DateTime)]
    [Display(Name = "Data Publicação")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime DataPublicacao { get; set; }

    [DataType(DataType.DateTime)]
    [Display(Name = "Data de Atualização")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime DataAtualizacao { get; set; }

    [Display(Name = "Fonte da Notícia")]
    public string TituloFonte { get; set; }

    [Display(Name = "Endereço da Fonte")]
    public string UrlFonte { get; set; }

    [Display(Name = "Visualizações")]
    public int? ViewNumber { get; set; }

    [Display(Name = "Nome do Entrevistado")]
    public string NomeEntrevistado { get; set; }

    [NotMapped]
    [DataType(DataType.Time)]
    [Display(Name = "Hora")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = @"{hh\:mm\:ss}")]
    public TimeSpan Hora { get; set; }

    public string ImageResizerType { get; set; }

    public bool Status { get; set; }

    [ForeignKey("Bloco")]
    public virtual int BlocoId { get; set; }

    [IgnoreDataMember]
    [Display(Name = "Bloco")]
    public virtual Bloco Bloco { get; set; }

    [ForeignKey("Editoria")]
    public virtual int EditoriaId { get; set; }

    [IgnoreDataMember]
    [Display(Name = "Editoria")]
    public virtual Editoria Editoria { get; set; }

    [ForeignKey("User")]
    public virtual int UserId { get; set; }

    [IgnoreDataMember]
    public virtual User User { get; set; }
}

Code of Controller:

[HttpPost]
[ValidateInput(false)]
[ValidateAntiForgeryToken]
public ActionResult Create(InsertEditNoticiaViewModel model)
{
    try
    {
        var noticia = model.Noticia;

        var blocos = _context.Blocos.ToList();

        foreach (var item in blocos)
        {
            item.Nome = item.Nome.Replace("_", " ");
        }

        if (!ModelState.IsValid)
        {
            model.Editorias = new SelectList(_context.Editorias.ToList(), "EditoriaId", "Nome", model.EditoriaSelect);
            model.Blocos = new SelectList(blocos, "BlocoId", "Nome", model.BlocoSelect);
            return View(model);
        }

        if (model.FotoBase == null)
        {
            noticia.UrlFotoCapa = "/Content/img/img-padrao.png";
        }
        else
        {
            var ext = Path.GetExtension(model.FotoBase.FileName);
            var foto = string.Concat(DateTime.Now, ext).Replace("/", "-").Replace(":", "-").Replace(" ", "-");
            const string localpath = "/Upload/Noticias/Capa/";
            var localFisicoImagem = Path.Combine(Server.MapPath(localpath), Path.GetFileName(foto));
            model.FotoBase.SaveAs(localFisicoImagem);

            var img = Image.FromStream(model.FotoBase.InputStream, true, true);
            var w = img.Width;
            var h = img.Height;

            model.Noticia.ImageResizerType = w > h ? "crop" : "max";
            model.Noticia.UrlFotoCapa = localpath + foto;
        }

        var editoria = _context.Editorias.Find(model.EditoriaSelect);
        noticia.Editoria = editoria;

        var user = UserRepo.GetLogedUser();

        noticia.User = user;

        var bloco = _context.Blocos.Find(model.BlocoSelect);
        noticia.Bloco = bloco;

        noticia.DataPublicacao = noticia.DataPublicacao.Add(model.Noticia.Hora);
        noticia.DataAtualizacao = noticia.DataPublicacao;
        noticia.Status = false;

        _context.Noticias.Add(noticia);
        _context.SaveChanges();

        var js = new JavaScriptSerializer();

        var log = new Log
        {
            Action = "CREATE",
            NoticiaId = noticia.NoticiaId,
            UserId = noticia.User.UserId,
            Date = DateTime.Now,
            UpdateDate = DateTime.Now,
            OriginalValues = js.Serialize(noticia.Texto),
            NewValues = null
        };

        _context.Logs.Add(log);
        _context.SaveChanges();

        return RedirectToAction("Index");
    }
    catch (Exception  e)
    {
        var blocos = _context.Blocos.ToList();

        foreach (var item in blocos)
        {
            item.Nome = item.Nome.Replace("_", " ");
        }

        model.Editorias = new SelectList(_context.Editorias.ToList(), "EditoriaId", "Nome", model.EditoriaSelect);
        model.Blocos = new SelectList(blocos, "BlocoId", "Nome", model.BlocoSelect);
        var error = e.Message;
        ModelState.AddModelError("", error.ToString(CultureInfo.InvariantCulture));
        return View(model);
    }
}

I’m doing exactly like the Editoria and the Bloco but not certain!

  • Instead of noticia.User = user; shouldn’t be noticia.UserId = userId;?

  • @ramaral No. This would cause the Entity Framework to insert another user record, because the information is not being observed by the context.

  • @Hermesautran You could put in your question the code of the following method: UserRepo.GetLogedUser();?

  • @Ciganomorrisonmendez I may not be seeing well, but what I mean is that the [Foreignkey("User")] is not being set, besides noticia.User = user; it would also be necessary noticia.UserId = noticia.User.UserId;

  • I found the problem, but I do not know why it happens, I will post as an answer to anyone who has the same problem later!

1 answer

1

I found the problem, I do not know why it happens but I will post as solved in case someone comes to have the same problem later.

In the following line:

var user = UserRepo.GetLogedUser();

noticia.User = user;

This static method GetLogedUser() simply do a search on the bank picking up the user who is currently logged in, follow the code below:

public static User GetLogedUser()
{
    if (!HttpContext.Current.User.Identity.IsAuthenticated) return null;

    var login = HttpContext.Current.User.Identity.Name;

    var context = new NewsContext();

    if (string.IsNullOrEmpty(login))
    {
        return null;
    }

    var user = context.Users.SingleOrDefault(u => u.Login == login && u.Status);
    return user;
}

But I don’t know why Objeto to notícia by saving him from a SaveChanges() in the Usuario also.

But when I do it this way:

var user = UserRepo.GetLogedUser();
noticia.User = _context.Users.FirstOrDefault(x => x.UserId == user.UserId);

And recorded only the ID of usuário and not a new registration in the bank.

  • 1

    This is because, in the correct command, you are asking for the context that will save the record of the news also observe the user, which was possibly not happening when using UserRepo.GetLogedUser();. Even if the user was correct in returning the static method, the context would understand that it would be a new user.

Browser other questions tagged

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