Microsoft.EntityFrameworkCore.dll 中发生类型 'Microsoft.EntityFrameworkCore.DbUpdateException' 的异常

An exception of type 'Microsoft.EntityFrameworkCore.DbUpdateException' occurred in Microsoft.EntityFrameworkCore.dll

我困扰了很长时间。让我们想象一下这个例子:

public class Coordinate {

     public int id {get;set;}
     public int x {get;set;}
     public int y {get;set;}
}
public class Planet {

     public int id {get;set;}
     public string name {get;set;}
     public Coordinate coordinate {get;set;}
}

我创建了两个模型,模型 Planet 具有模型坐标作为属性。 现在想象一下,我在代码的某处创建了一个坐标并将其存储在数据库中。 想象一下这是坐标:

Coordinate c = new Coordinate();
c.x = 1;
c.y = 2;

然后我将它添加到我的数据库并保存。

但是当我创建一个行星时,我做了:

planet.coordinate = c;

然后我尝试将它添加到数据库中,但出现以下错误:

An exception of type 'Microsoft.EntityFrameworkCore.DbUpdateException' occurred in Microsoft.EntityFrameworkCore.dll but was not handled in user code

Additional information: An error occurred while updating the entries. See the inner exception for details.

我知道我可以将属性 public Coordinate coordinate 更改为 public int coordinate_id,但我想改为使用坐标模型来执行此操作。

我正在使用 ASP NET CORE 1.0

胸罩

查看内部异常将使您更详细地了解问题所在。

执行此操作,在调试模式下,显示异常时。单击查看详细信息并按照树的顺序进行操作,直到找到内部异常。

可能存在重复行、主键问题或结构问题。

你的问题是,此时c已经有了一个Id。

对于 planet.Add,行星及其所有坐标都将在您的 DbSet 中设置为已添加,并且在调用 SaveChanges 时,将创建插入语句。 (这里我假设你的列和你的 Id 属性 自动递增)

当SaveChanges完成后,EF会看到数据库中有行星,但是刚才添加的坐标的Id不同(被DBMS修改了,所以现在坐标在你的数据库中有两次,有两个不同的 ID),因此它会预期出现问题并抛出此异常。

当您没有重复条目的问题时,将 Id 设置为 null 或 0。否则,有两个解决方案:

-只设置外键属性,不设置导航属性

-只调用 SaveChanges 一次(例如,只添加行星,但是添加坐标关系修复应该会导致相同的结果)

我遇到了同样的问题,我意识到我正在创建多个实例来访问数据库。 所以我采取的解决方案是创建一个只进行一次访问的 class。

class SingletonContext {
    private static Context _context;
    public static Context GetInstance() {
        if (_context == null) {
            _context = new Context();
        }
        return _context;
    }
}

在每次访问数据库层时,我都会调用 GetInstance(),如下所示:

private static Context _context = SingletonContext.GetInstance();