EF Core One ко многим добавление нового объекта - PullRequest
0 голосов
/ 19 января 2019

Я пробовал много способов, но я все еще сталкиваюсь с различными видами ошибок для каждого решения.Я пытался остановить отслеживание, пытался сам добавить challenge, обновить competition, но все они, похоже, не работают.

У меня в основном есть 1 конкурент на многие проблемы, и в этом сценарии 1competition и 1 challenge уже присутствуют, и я добавляю еще один challenge, который имеет внешний ключ, связывающий с competition.Я понимаю, что раньше задавал похожий вопрос , но это было для массового создания 1 конкурса для многих категорий.Я думаю, что это больше похоже на операцию обновления, которая, кажется, не работает.Очень ценю вашу помощь!:)

InvalidOperationException: экземпляр типа объекта «Вызов» не может быть отслежен, поскольку другой экземпляр с таким же значением ключа для {'ID'} уже отслеживается.При подключении существующих объектов убедитесь, что подключен только один экземпляр объекта с данным значением ключа.Рекомендуется использовать 'DbContextOptionsBuilder.EnableSensitiveDataLogging', чтобы увидеть конфликтующие значения ключа.

Competition Класс модели:

public class Competition
{
    [Key]
    public int ID { get; set; }

    public ICollection<CompetitionCategory> CompetitionCategories { get; set; }
    public ICollection<Challenge> Challenges { get; set; }
}

Challenge Класс модели:

public class Challenge
{
    [Key]
    public int ID { get; set; }

    [ForeignKey("CompetitionID")]
    public int CompetitionID { get; set; }
    [Display(Name = "Competition Category")]
    [ForeignKey("CompetitionCategoryID")]
    public int CompetitionCategoryID { get; set; }
}

Контроллер:

public async Task<IActionResult> Create([Bind("ID,XXX,CompetitionID,CompetitionCategoryID")] Challenge challenge)
{
    var competition = await _context.Competitions
    .Include(c => c.CompetitionCategories)
    .Include(c1 => c1.Challenges)
    .AsNoTracking()
    .FirstOrDefaultAsync(m => m.ID == challenge.CompetitionID);

    if (ModelState.IsValid)
    {
        //_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        competition.Challenges.Add(challenge);

        _context.Update(competition);
        _context.Entry(competition).State = EntityState.Detached;
        _context.Entry(competition.Challenges).State = EntityState.Detached;
        await _context.SaveChangesAsync();
        //_context.Add(challenge);
        //await _context.SaveChangesAsync();
        //return RedirectToAction(nameof(Index));
        return RedirectToAction("Index", "Challenges", new { id = challenge.CompetitionID });
    }

     return View();
 }

Обновление: Я на самом деле пытался просто добавить challenge сам, но он также выдает другую ошибку.Действительно в растерянности того, что делать.

SqlException: Невозможно вставить явное значение для столбца идентификаторов в таблице «Вызовы», когда для IDENTITY_INSERT установлено значение OFF.System.Data.SqlClient.SqlCommand + <> c.b__122_0 (результат задачи)

DbUpdateException: при обновлении записей произошла ошибка.Смотрите внутреннее исключение для деталей.Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync (соединение IRelationalConnection, CancellationToken cancellationToken)

Обновление 2: удаление идентификатора из привязки работает, поскольку в него передается и отслеживается какое-то неизвестное значение идентификатора.Ответ Ивана на добавление нового объекта с внешним ключом правильный.

public async Task<IActionResult> Create([Bind("XXX,CompetitionID,CompetitionCategoryID")] Challenge challenge)
{
    //Codes here
    _context.Add(challenge);
    await _context.SaveChangesAsync();
}

1 Ответ

0 голосов
/ 19 января 2019

Работа с отключенными объектами не легка и требует различных методов в зависимости от наличия / отсутствия навигации / обратной навигации и свойств FK в модели объекта.

Ваш Challenge класс имеет явные свойства FK и не имеет навигационных свойств. Добавление нового объекта, как это самая простая операция - просто вызовите DbContext.Add или DbSet.Add:

_context.Add(challenge);
await _context.SaveChangesAsync();

Однако полученное вами исключение заставляет меня думать, что объект Challenge, полученный методом Create, имеет свойство PK Id, заполненное значением существующего Challenge. Если вы действительно хотите добавить новые Challenge и Id генерируется автоматически, исключите Id из привязки или убедитесь, что для него установлено значение 0 (ноль) перед вызовом Add.

Для получения дополнительной информации см. Отключенные объекты и соответствующие ссылки в документации EF Core.

...