尝试添加项目时在实体框架中出现错误

Posted

技术标签:

【中文标题】尝试添加项目时在实体框架中出现错误【英文标题】:Getting error in Entity Framework when trying to add an item 【发布时间】:2018-06-25 20:56:37 【问题描述】:

尝试将项目添加到数据库上下文时出现以下错误。我在 Web API 项目中使用实体框架。示例代码如下所示。

例外

System.Data.Entity.Infrastructure.DbUpdateException HResult=0x80131501 消息=更新 条目。有关详细信息,请参阅内部异常。来源=实体框架 堆栈跟踪:在 System.Data.Entity.Internal.InternalContext.SaveChanges() 在 System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 在 System.Data.Entity.DbContext.SaveChanges() 在 WebApiSample.Controllers.OrdersController.Orders(Order neworder) 中 C:\Repository\bitbucket\OtherProjects\WebApiSample\WebApiSample\Controllers\OrdersController.cs:line 173 在 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.c__DisplayClass10.b__9(对象 实例,对象 [] 方法参数)在 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(对象 实例,对象 [] 参数)在 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext,IDictionary`2 参数,CancellationToken 取消令牌)

内部异常1:UpdateException:更新时出错 条目。有关详细信息,请参阅内部异常。

内部异常 2:SqlException:无法将值 NULL 插入 列“订单号”,表 'C:\REPOSITORY\BITBUCKET\OTHERPROJECTS\WEBAPISAMPLE\WEBAPISAMPLE\APP_DATA\DATA.MDF.dbo.Orders'; 列不允许空值。插入失败。该声明已 终止。

这段代码是用 Web API 的 POST 方法编写的:

[HttpPost]
public IHttpActionResult Orders(Order neworder)

    if (neworder == null)
    
        return BadRequest();
    

    string uri = Url.Link("DefaultApi", new  id = neworder.OrderNumber );

    try
    
        using (OrderContext db = new OrderContext("ConnectionString"))
        
            if (neworder == null)
            
                return BadRequest();
            

            db.Orders.Add(neworder);
            db.SaveChanges();
        
    
    catch (Exception ex)
    
        throw ex;
    

    return Created<Order>(uri, neworder);

Order 实体:

namespace WebApiSample.Models

    public class Order
    
        [Key]
        public int OrderNumber  get; set; 

        public Decimal OrderAmount  get; set; 
        public DateTime OrderDate  get; set; 

        public string CustomerName  get; set; 
        public int OrderQty  get; set; 

        [Column("ShippingStatusFlag")]
        public string ShippingStatus  get; set; 

        public virtual ICollection<OrderItems> Items  get; set; 
    

OrderItems 实体:

namespace WebApiSample.Models

    [Table("OrderItems")]
    public class OrderItems
    
        [Key]
        [ForeignKey("Order")]
        [Column(Order =1)]
        public int OrderNumber  get; set; 

        [Key]
        [Column(Order = 2)]
        public int ItemID  get; set; 

        [Key]
        [Column(Order = 3)]
        public int ItemSeq  get; set; 
        public Decimal ItemPrice  get; set; 
        public string ItemDescription  get; set; 
        public int ItemQty  get; set; 

        public virtual Order Order  get; set; 
    

POST请求正文中传递的数据是


        "OrderNumber": 9000,
        "OrderAmount": 20,
        "OrderDate": "2018-01-15T00:00:00",
        "CustomerName": "TEST",
        "OrderQty": 3,
        "ShippingStatus": "N",
        "Items": [
            
                "OrderNumber": 9000,
                "ItemID": 535,
                "ItemSeq": 1,
                "ItemPrice": 10,
                "ItemDescription": "Plantronics Bluetooth Headset",
                "ItemQty": 1,
                "order": null
            ,
             
                "OrderNumber": 9000,
                "ItemID": 536,
                "ItemSeq": 2,
                "ItemPrice": 5,
                "ItemDescription": "Yellow StickyNote 100ct",
                "ItemQty": 1,
                "order": null
            ,
             
                "OrderNumber": 9000,
                "ItemID": 601,
                "ItemSeq": 3,
                "ItemPrice": 5,
                "ItemDescription": "Black Think Permanent Marker",
                "ItemQty": 1,
                "order": null
            
        ]
    

什么可能导致此问题?我在这里做错了什么?

【问题讨论】:

异常信息是什么? 您刚刚显示了堆栈跟踪。导入问题中的完整异常消息 对了,把throw ex;换成throw;怎么样? 也许您应该为Order 类中的OrderNumber 属性设置属性DatabaseGenerated(DatabaseGeneratedOption.None)。您的模型(期望自动增量键)和您的数据库/使用情况之间可能存在不匹配,期望显式键设置......或者 OrderNumber 条目是否可以引用现有数据库行? @grek40:您在Order 类中将[DatabaseGenerated(DatabaseGeneratedOption.None)] 添加到OrderNumber 属性的解决方案解决了我的问题。谢谢! 【参考方案1】:

使用DatabaseGeneratedAttribute 修改您的OrderNumber 属性

public class Order

    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int OrderNumber  get; set; 

    ...

背景:当单个整数属性标记为Key时,默认设置为DatabaseGeneratedOption.Identity。使用此设置,EF 假定数据库将负责分配新的主键值。所以对于状态为Added 的实体,key 列将被忽略,不会传输到数据库中。

这解释了为什么错误与代码中甚至不能为空的属性的 NULL 值有关。

【讨论】:

以上是关于尝试添加项目时在实体框架中出现错误的主要内容,如果未能解决你的问题,请参考以下文章

ADO.NET 实体框架 - 带有实体框架 6 的 Oracle

实体框架超时

实体框架运行转换代码时引发异常

将 GPUImage 框架添加到 IOS 项目

无法让实体框架连接

有没有办法避免在我的 UI 项目中添加对实体框架的引用而不使用 Web 服务作为中间人?