Ошибка сохранения записи в базе данных.Использование Entity Framework.Невозможно вставить явное значение для столбца идентификаторов - PullRequest
0 голосов
/ 29 января 2019

Я получаю сообщение об ошибке, но не могу понять, почему он пытается что-то сохранить в таблице «Приоритет».Из базы данных таблица приоритетов имеет первичный ключ идентификатора.ForeignKey для таблицы запросов имеет приоритет.

Вот ошибка, которую я получаю: «Произошла ошибка при обновлении записей. Подробности см. Во внутреннем исключении. Невозможно вставить явное значение для столбца идентификации в таблице« Приоритет », когда для IDENTITY_INSERT установлено значение OFF.»

Похоже, что при вызове db.SaveChangesAync (); он пытается что-то сохранить в таблице приоритетов, но не должен.В таблице Приоритет есть элементы, так что это тоже не проблема.Модель, возвращаемая из контроллера, имеет все необходимое для завершения ввода.

Вот расширение запроса

public static async Task AddRequest(this AppDbContext db, Request request)
    {
        if (await request.Validate(db))
        {
            request.DateSubmitted = DateTime.Now;
            request.LastModified = DateTime.Now;
            request.PriorityId = request.Priority.Id;
            request.SiteId = request.Site.Id;
            await db.Requests.AddAsync(request);
            await db.SaveChangesAsync();

            foreach (var item in request.RequestItems)
            {
                await db.AddItems(item, request.Id);
            }
        }
    }
private static async Task<bool> Validate(this Request model, AppDbContext db)
    {
        if (string.IsNullOrEmpty(model.Subject))
        {
            throw new Exception("Subject must be filled in");
        }

        var check = model.Id > 0 ?
            await db.Requests.FirstOrDefaultAsync(x => x.Subject.ToLower() == model.Subject.ToLower() && x.Id == model.Id) :
            await db.Requests.FirstOrDefaultAsync(x => x.Subject.ToLower() == model.Subject.ToLower() && x.UserId == model.UserId);

        if (check != null)
        {
            throw new Exception("The provided Request already exists");
        }

        return true;
    }

Модель запроса

public class Request
{
    public int Id { get; set; }
    public int PriorityId { get; set; }
    public int SiteId { get; set; }
    public int UserId { get; set; }
    public string Justifications { get; set; }
    public Guid Guid { get; set; }
    public string Subject { get; set; }
    public string Requirement { get; set; } 
    public string Mission { get; set; }
    public DateTime DateSubmitted { get; set; }
    public DateTime LastModified { get; set; }

    public bool IsRecurring { get; set; }
    public DateTime? RenewalDate { get; set; }

    public bool IsApproved { get; set; }
    public bool IsComplete { get; set; }

    public Priority Priority { get; set; }
    public Site Site { get; set; }
    public User User { get; set; }


    public List<ItemGroup> ItemGroups { get; set; }
    public List<RequestAttachment> RequestAttachments { get; set; }
    public List<RequestItem> RequestItems { get; set; }
}

}

Тогда вот модель приоритета

public class Priority
{
    public int Id { get; set; }
    public string Label { get; set; }
    public bool IsDeleted { get; set; }

    public List<Request> Requests { get; set; }
}

Вот обновленная и действующая версия моей задачи AddRequest: Спасибо @ Imantas

public static async Task AddRequest(this AppDbContext db, Request request)
    {
        if (await request.Validate(db))
        {
            request.DateSubmitted = DateTime.Now;
            request.LastModified = DateTime.Now;
            request.PriorityId = request.Priority.Id;
            request.SiteId = request.Site.Id;
            db.Priorities.Attach(request.Priority);
            db.Sites.Attach(request.Site);
            await db.Requests.AddAsync(request);
            await db.SaveChangesAsync();

            foreach (var item in request.RequestItems)
            {
                await db.AddItems(item, request.Id);
            }
        }
    }

1 Ответ

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

Ваш request.Priority объект либо отсоединен от DbContext, либо никогда не был присоединен.Также может случиться, что вы получили его из другого экземпляра DbContext.Вы не указали контекст, откуда он приходит к методу, поэтому трудно сказать, какова точная причина.Таким образом, трекер изменений идентифицирует его как новую сущность и пытается вставить его.Поскольку он Id уже установлен, база данных отклоняет эту вставку.

У вас есть несколько вариантов здесь.Одним из них является ручное присоединение request.Priority к текущему DbContext с состоянием Unchanged.Другой проще.Просто установите request.Priority = null; сразу после установки request.PriorityId = request.Priority.Id.Таким образом, трекер изменений не увидит сущность, которую вы не хотите вставлять, и не попытается вставить ее в базу данных.Отношение (внешний ключ) по-прежнему будет установлено правильно, поэтому об этом не стоит беспокоиться.

Однако, если вам нужно использовать отношение request.Priority после сохранения, вам необходимо перезагрузить объект из базы данных или установить его снова.,В этом случае первый вариант может быть лучше.

...