Entity Framework Core Update Duplicating

asp.net-core c# entity-framework-core

Question

When attempting to update an entity with a child entity collection, each member of the child collection is duplicated. Why are the child entities being duplicated when using the Update method in the controller?

This application uses ASP.NET Core 2.1 and Entity Framework Core, that connects to MS SQL Server LocalDB in Visual Studio 2017.

ParentEntity.cs

namespace MyProject.Models
{

    public enum EntityType { Type1, Type2, Type3}

    public class ParentEntity
    {
        public int ParentEntityID { get; set; }

        public string Text { get; set; }

        public EntityType EntityType { get; set; }

        public ICollection<ChildEntity> ChildEntities { get; set; }

    }
}

ChildEntity.cs

namespace MyProject.Models
{
    public class ChildEntity
    {
        public int ChildEntityID { get; set; }
        public string ChildEntityText { get; set; }

        public int ParentEntityId { get; set; }
        public ParentEntity ParentEntity { get; set; }
    }
}

EditEntity.cshtml

@model ParentEntity

<h1>Edit Entity</h1>
<form asp-controller="Entity" asp-action="Edit" method="post">
    <input type="hidden" asp-for="ParentEntityID" />
    <input type="hidden" asp-for="EntityType" />
    <label asp-for="Text"></label>
    <input asp-for="Text" class="form-control" />

    @{ int i = 1; var a = Model.ChildEntities.ToArray(); }
    @for(var c = 0; c < Model.ChildEntities.Count(); c++)
    {
        <label>Child Entity @i</label>
        <input name="ChildEntities[@c].ChildEntityText" value="@a[c].ChildEntityText" />
        i++;
    }

    <button type="submit">Save</button>
</form>

EntityController.cs

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ParentEntityID, Text, EntityType, ChildEntities")] ParentEntity pa)
{
    if (id != pa.ParentEntityId)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            context.Update(pa);
            await context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {

        }
        return RedirectToAction("EditEntity");
    }
    return View(pa);
}
1
2
6/30/2018 2:34:34 PM

Popular Answer

First thing I would check is if the ChildEntityIds on the ChildEntities are actually set when they come in from the controller. If the ids are 0 EF will think they are new entities and do an insert.

If they do have ids set to non-zero ints, I would try do a loop over them and attach the entities so the context knows about them. Something like:

foreach(var child in pa.children){
    context.Attach(child);
}

await context.SaveChanges();
1
6/29/2018 7:00:34 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow