实体框架核心:Npgsql.PostgresException:23505:重复键值违反唯一约束

时间:2016-08-17 07:44:55

标签: c# entity-framework postgresql npgsql

当我尝试从asp.net web api插入用户时,我收到以下异常: Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> Npgsql.PostgresException: 23505: duplicate key value violates unique constraint

以下是我的实体模型:角色和用户。每个用户链接到一个角色的位置。

public class Role
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime? LastUpdate { get; set; }
}

public class User
{
    public int Id { get; set; }
    public Role role { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? LastLogin { get; set; }
}

我的终点看起来像这样:

[HttpPost]
    public async Task<IActionResult> PostUser([FromBody] User user)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        user.DateCreated = DateTime.Now;
        //user.LastLogin = DateTime.Now;
        var hashedPassword = BCrypt.Net.BCrypt.HashPassword(user.Password);
        user.Password = hashedPassword;
        _context.User.Add(user);
        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateException ex)
        {
            Console.WriteLine(ex.Message);
            if (UserExists(user.Id))
            {
                return new StatusCodeResult(StatusCodes.Status409Conflict);
            }
            else
            {
                Console.WriteLine(ex.Message);
            }
        }

        return CreatedAtAction("GetUser", new { id = user.Id }, user);
    }

请注意,在进行一些调试之后,从主体传递的新用户通过了下面的检查,这意味着我的模型是有效的:

if (!ModelState.IsValid)
{
    return BadRequest(ModelState);
}

但最后,结束了catch块并打印出上述异常。

似乎尝试创建链接到新用户的角色。我现在不知道为什么因为角色已经存在。

这个问题可能是什么原因?

2 个答案:

答案 0 :(得分:1)

如果您的角色实例已存在,则需要附加它以让EF知道它已存在于数据库中。否则,EF假定它是一个新实例并尝试重新创建它,从而导致唯一的约束违规。这就是EF的工作原理,您可以阅读https://msdn.microsoft.com/en-us/data/jj592676.aspx了解更多详情(它关于EF6,但也适用于EFCore)。

请注意,您也可以在自己的答案(_context.Role.FirstOrDefault(...))中从数据库加载现有角色,但这可能涉及不必要的数据库查询。只要您能够在.NET中完全构建Role对象,您需要做的就是将其附加到您的上下文中,EF将理解它应该已经存在于数据库中。< / p>

答案 1 :(得分:0)

绝对是与实体框架相关的东西。虽然我正在创建附加到现有角色的新用户,但还是尝试重新创建角色。在转到保存实体之前,我转到了我的指向并添加了以下行,以确保附加到用户的角色使用与保存用户相同的数据库上下文:

 var rl = _context.Role.FirstOrDefault(r=> r.Id==user.role.Id);
 user.role= rl;

现在它有效......

当我必须保存引用其他对象的对象时,是否需要这样做?

相关问题