Entity framework 更新条目重复键

Entity framework Update entry duplicate key

我有一个这样的实体:

public class Notification
{
    public int Id { get; set; }
    public bool IsReminderActive { get; set; }
    public bool IsInvitationActive { get; set; }
    public int ContractId { get; set; }
    public bool IsActive { get; set; }
}

如果我想更新一个条目或创建一个新条目,我正在尝试这样的事情:

public async Task<bool> Post(Notification notificationEmail)
    {
        try
        {
            if (!_context.Notification.Any(x => x.ContractId == notificationEmail.ContractId))
            {
                _logger.LogInformation($"Creating new Notification for contract {notificationEmailType.ContractId}");
                _context.Notification.Add(notificationEmail);
            }
            else
            {
                var update = _context.Notification.First(x => x.ContractId == notificationEmail.ContractId);
                update.IsInvitationActive = notificationEmail.IsInvitationActive;
                update.IsReminderActive = notificationEmail.IsReminderActive;
                _logger.LogInformation($"Updating Notification for contract {notificationEmail.ContractId}");
                _context.Notification.Update(update);
            }
            await _context.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError("Error trying to create/update Notification", ex);
            return false;
        }
        return true;
    }

我这样做了更新部分,因为如果我尝试使用 notificationEmail 变量更新条目,我会遇到 ContractId 重复键的错误。

SqlException: Cannot insert duplicate key row in object 'dbo.Notification' with unique index 'IX_Notification_ContractId'. The duplicate key value is (4).

更新代码有更好的写法吗?

首先你应该在 PUTPATCH 请求上移动 Update 代码,然后你不需要将 id 传递给 post 当您创建新记录时

是的,您不需要调用 Update(),因为您在使用 _context.Notification.First 时已经有一个被跟踪的实例。 最初只是尝试获取一个跟踪实例,然后在找到时更新它。

    public async Task<bool> Post(Notification notificationEmail)
    {
        try
        {
            var notification = _context.Notification.FirstOrDefault(x => x.ContractId == notificationEmail.ContractId);
            if (notification == null)
            {
                _logger.LogInformation($"Creating new Notification for contract {notificationEmailType.ContractId}");
                _context.Notification.Add(notificationEmail);
            }
            else
            {
                notification.IsInvitationActive = notificationEmail.IsInvitationActive;
                notification.IsReminderActive = notificationEmail.IsReminderActive;
                _logger.LogInformation($"Updating Notification for contract {notificationEmail.ContractId}");
            }
            await _context.SaveChangesAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError("Error trying to create/update Notification", ex);
            return false;
        }
        return true;