Дублирование обновления ядра Entity Framework - PullRequest
0 голосов
/ 29 июня 2018

При попытке обновить сущность с помощью коллекции дочерних сущностей каждый член дочерней коллекции дублируется. Почему дочерние объекты дублируются при использовании метода Update в контроллере?

Это приложение использует ASP.NET Core 2.1 и Entity Framework Core, которые подключаются к MS SQL Server LocalDB в 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);
}

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Все, что требовалось, это добавить подписку к каждой строке цикла for в представлении.

<input type="hidden" name="ChildEntities[@c].ChildEntityID" value="@a[c].ChildEntityText" class="form-control" />
0 голосов
/ 29 июня 2018

Первое, что я хотел бы проверить, это то, что ChildEntityIds на ChildEntities действительно установлены, когда они поступают из контроллера. Если идентификаторы равны 0, EF будет думать, что они являются новыми объектами, и сделает вставку.

Если у них действительно установлены идентификаторы, отличные от нуля, я бы попробовал сделать цикл над ними и прикрепить сущности, чтобы о них знал контекст. Что-то вроде:

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

await context.SaveChanges();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...