【发布时间】:2017-08-10 20:34:22
【问题描述】:
我正在使用 .Net Web API 核心和 Entity Framework Core 为产品商店构建 API。我的产品实体如下所示
public class Product
{
[Key]
public long ID { get; set; }
[Required]
[MaxLength(80)]
public string Name { get; set; }
............
}
我有订单实体是
public class Order
{
[Key]
public long ID { get; set; }
public List<OrderItem> OrderItems { get; set; }
..........
}
我有 OrderItem 实体,它是在用户将产品添加到卡片时创建的,但尚未创建订单时:
public class OrderItem
{
[Key]
public long ID { get; set; }
public string UID { get; set; }
public long OrderID { get; set; }
public Order Order { get; set; }
[Required]
public long ProductID { get; set; }
public Product Product { get; set; }
public int Quantity { get; set; }
}
它告诉用户已将具有此数量的 ProductID(FK) 的产品添加到他的卡中。但是还没有创建订单(所以 OrderID FK 还为空)。
当我发出将带有 ProductID、Quantity 和 UID 的 OrderItem 添加到我的数据库的发布请求时,如下所示:
[HttpPost]
public IActionResult Post([FromBody]JObject newItem)
{
OrderItem oItem = newItem.ToObject<OrderItem>();
context.OrderItems.Add(oItem);
context.SaveChanges();
return StatusCode(200);
}
在我调用 SaveChanges() 的行上抛出一个带有文本“FOREIGN KEY Constraint failed”的异常。我正在添加一个具有有效 ProductID 的对象,JObject 被正常投射。我尝试使用 SQLIte 浏览器添加相同的对象手动,它没有给出任何错误。关于我还没有给出值的 OrderID,外键可以为空,不是吗?
请帮助我,我无法理解导致此问题的原因。 附言我在 Mac OS 上使用 Visual Studio 2017。
UPD。
这是输出(我安慰 JObject 看我是否正确):
Application started. Press Ctrl+C to shut down.
Jobject received is:{
"ProductID": 2,
"UID": "6c523a76-dd6e-7782-2bc9-9b8baba36e5d",
"Quantity": "1"
}
OrderItem casted is: ProductID=2; UID=6c523a76-dd6e-7782-2bc9-9b8baba36e5d
fail: Microsoft.EntityFrameworkCore.DbContext[1]
An exception occurred in the database while saving changes.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> Microsoft.Data.Sqlite.SqliteException: SQLite Error 19: 'FOREIGN KEY constraint failed'.
at Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC(Int32 rc, Sqlite3Handle db)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMethod, IReadOnlyDictionary`2 parameterValues, Boolean closeConnection)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(Tuple`2 parameters)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> Microsoft.Data.Sqlite.SqliteException: SQLite Error 19: 'FOREIGN KEY constraint failed'.
at Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC(Int32 rc, Sqlite3Handle db)
at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMethod, IReadOnlyDictionary`2 parameterValues, Boolean closeConnection)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(Tuple`2 parameters)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
【问题讨论】:
-
您能否添加更多异常(例如 FK 约束失败的字段)?
-
@Quentin,似乎与我的问题相似,但我无法从中获得任何帮助
-
IReadOnlyList和entriesToSave的组合有什么建议吗?
标签: c# entity-framework sqlite asp.net-web-api foreign-keys