将SaveChanges()方法与EF核心一起使用时出错

时间:2020-05-13 10:08:35

标签: c# entity-framework asp.net-core entity-framework-core

在以下代码中,在第一个_context.SaveChanges();循环内向FeedbackComments添加新记录时,在foreach中收到错误。错误为New transaction is not allowed because there are other threads running in the session.。任何想法为什么会这样?

顺便说一句,当SaveChanges在外部循环之后仅被调用一次时,我仍然收到相同的错误。

List<FeedbackComment> feedbackComments = comments.Select(c => new FeedbackComment
{
    Id = c.Id,
    CommentText = c.Content,
    SubmissionId = submissionId,
    UserDisplayName = c.Author.DisplayName,
    DateCreated = c.CreatedTime.GetValueOrDefault(),
    FeedbackReplies = c.Replies.Select(r => new FeedbackReply
    {
        Id = r.Id,
        UserDisplayName = r.Author.DisplayName,
        ReplyText = r.Content,
        DateCreated = r.CreatedTime.GetValueOrDefault(),
        FeedbackCommentId = c.Id
    }).ToList()
}).ToList();

_context.SaveChanges();


foreach (FeedbackComment c in feedbackComments)
{
    if (!_context.FeedbackComments.Any(fc => fc.Id == c.Id))
    {
        ApplicationUser commentOwner = _context.ApplicationUsers.FirstOrDefault(au => au.GoogleDisplayName == c.UserDisplayName);

        if(commentOwner != null)
        {
            c.UserId = commentOwner.Id;

            _context.FeedbackComments.Add(c);
            newComments = true;
            _context.SaveChanges();

        }

    }


    foreach (FeedbackReply r in c.FeedbackReplies)
    {
        if (!_context.FeedbackReplies.Any(fr => fr.Id == r.Id))
        {
            ApplicationUser replyOwner = _context.ApplicationUsers.FirstOrDefault(au => au.GoogleDisplayName == c.UserDisplayName);

            if (replyOwner != null)
            {
                r.UserId = replyOwner.Id;

                _context.FeedbackReplies.Add(r);
                newComments = true;
                _context.SaveChanges();

            }
        }

    }
}

2 个答案:

答案 0 :(得分:0)

当您尝试使用事务保存更改时,应等待直到其他事务完成。另一方面,等待上一个事务完成将导致严重的性能问题。 您应该像这样将_context.SaveChanges();放在foreach循环之外:

foreach (FeedbackReply r in c.FeedbackReplies)
{
    if (!_context.FeedbackReplies.Any(fr => fr.Id == r.Id))
    {
        ApplicationUser replyOwner = _context.ApplicationUsers.FirstOrDefault(au => au.GoogleDisplayName == c.UserDisplayName);

        if (replyOwner != null)
        {
            r.UserId = replyOwner.Id;
            _context.FeedbackReplies.Add(r);
            newComments = true;
        }
    }
}
_context.SaveChanges();

在上面的代码中,所有更改都在一个事务中应用于数据库。

答案 1 :(得分:0)

为什么在获取初始数据后调用SaveChanges?如哈迪所说,如果您不使用它而只调用一次SaveChanges,那么它应该可以工作。