将记录保存到数据库时出错。使用 Entity Framework。无法为标识列插入显式值

Error saving record to database. Using Entity Framework. Cannot insert explicit value for identity column

我收到一条错误消息,但无法弄清楚为什么它要尝试将任何内容保存到 'Priority' table。在数据库中,Priority table 的主键为 Id。 ForeignKey on Request Table 是 PriorityId。

这是我收到的错误: "An error occurred while updating the entries. See the inner exception for details. Cannot insert explicit value for identity column in table 'Priority' when IDENTITY_INSERT is set to OFF."

似乎在调用 db.SaveChangesAync(); 时,它试图将某些内容保存到优先级 Table,但它不应该。优先级 table 中有项目,所以这也不是问题。从控制器传回的模型具有完成输入所需的一切。

这是请求扩展

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);
            }
        }
    }

您的 request.Priority 实体与 DbContext 分离或从未附加。也可能是您从不同的 DbContext 实例中检索到它。您没有向该方法提供它来自何处的上下文,因此很难说出确切原因是什么。 这样,更改跟踪器将其识别为新实体并尝试将其插入。因为它已经设置了 Id,所以数据库拒绝了这个插入。

这里有多种选择。 其中之一是手动将 request.Priority 附加到具有 Unchanged 状态的当前 DbContext。 另一个更简单。只需在设置 request.PriorityId = request.Priority.Id 后立即显式设置 request.Priority = null;。这样更改跟踪器将看不到您不想插入的实体,也不会尝试将其插入数据库。关系(外键)仍将正确设置,所以不用担心。

但是如果保存后需要使用request.Priority关系,则需要从数据库中重新加载实体或重新设置。在这种情况下,第一个选项可能更好。