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();
我困扰了很长时间。让我们想象一下这个例子:
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();