c# – 使用EF更新PK时出错
发布时间:2020-12-15 21:19:42 所属栏目:百科 来源:网络整理
导读:我正在尝试使用EF 4.1(POCO)在Northwind数据库的Order_Details表中进行更新. 该表定义为: [MetadataType(typeof(Order_DetailMetadata))]public partial class Order_Detail{ public int OrderID { get; set; } public int ProductID { get; set; } public
我正在尝试使用EF 4.1(POCO)在Northwind数据库的Order_Details表中进行更新.
该表定义为: [MetadataType(typeof(Order_DetailMetadata))] public partial class Order_Detail { public int OrderID { get; set; } public int ProductID { get; set; } public decimal UnitPrice { get; set; } public short Quantity { get; set; } public float Discount { get; set; } public virtual Order Order { get; set; } public virtual Product Product { get; set; } } public class Order_DetailMetadata { [Key] [Required] [DisplayNameLocalized("Model_OrderDetail_OrderID_DisplayName")] public int OrderID { get; set; } [Key] [Required] [DisplayNameLocalized("Model_OrderDetail_ProductID_DisplayName")] public int ProductID { get; set; } [Required] [Range(0.00,9999.99,ErrorMessageResourceType = typeof(Messages),ErrorMessageResourceName = "Model_Range_Float_Error")] [DisplayNameLocalized("Model_OrderDetail_UnitPrice_DisplayName")] public decimal UnitPrice { get; set; } [Required] [Range(1,short.MaxValue,ErrorMessageResourceName = "Model_Range_Integer_Error")] [DisplayNameLocalized("Model_OrderDetail_Quantity_DisplayName")] public short Quantity { get; set; } [Required] [DisplayNameLocalized("Model_OrderDetail_Discount_DisplayName")] [Range(0.00,1.00,ErrorMessageResourceName = "Model_Range_Float_Error")] public float Discount { get; set; } } 问题是,当我尝试使用新产品更新OrderDetail项时,我得到异常: 属性“ProductID”是对象的关键信息的一部分,无法修改. 代码是: int orderId = (int)detailsList.DataKeys[e.ItemIndex]["OrderID"]; int productId = (int)detailsList.DataKeys[e.ItemIndex]["ProductID"]; Order_Detail detail = repository.GetOrderDetail(orderId,productId); detail.ProductID = int.Parse(e.NewValues["ProductID"] as string,CultureInfo.CurrentCulture); detail.UnitPrice = decimal.Parse(e.NewValues["UnitPrice"] as string,CultureInfo.CurrentCulture); detail.Quantity = short.Parse(e.NewValues["Quantity"] as string,CultureInfo.CurrentCulture); detail.Discount = float.Parse(e.NewValues["Discount"] as string,CultureInfo.CurrentCulture); repository.UpdateOrderDetail(detail); repository.Save(); 我做了一些谷歌并找到了[this solution],说这样做的方法是创建新产品的新实例并关联到Order_Detail的产品导航属性. 但这样做我得到另一个例外: 发生了引用完整性约束冲突:当依赖对象为Unchanged时,除非将其设置为关联的主体对象,否则无法更改作为参照完整性约束一部分的主键属性.必须跟踪主要对象,并且不标记为删除. 修改后的代码: int orderId = (int)detailsList.DataKeys[e.ItemIndex]["OrderID"]; int productId = (int)detailsList.DataKeys[e.ItemIndex]["ProductID"]; int newProductId = int.Parse(e.NewValues["ProductID"] as string,CultureInfo.CurrentCulture); Order_Detail detail = repository.GetOrderDetail(orderId,productId); detail.UnitPrice = decimal.Parse(e.NewValues["UnitPrice"] as string,CultureInfo.CurrentCulture); Product newProduct = null; // the product has been changed (it is part of the PK and cannot be directly changed) if (productId != newProductId) { // get an instance of the new product newProduct = repository.GetProduct(newProductId); // update the detail item with the new product instance detail.Product = newProduct; } repository.UpdateOrderDetail(detail); repository.Save(); 我该怎么做才能让用户更改详细信息项中的产品?我真的不喜欢删除整个记录并使用新产品重新创建它的想法.闻起来很糟糕! 谢谢! 解决方法
桌子设计很差.实际上,您必须删除并重新添加整行.
正确的设计将有一个单独的列作为Order Details表的主键(自动增量). 除了您发现的限制之外,该表不支持客户购买一个,以半价购买一个的情况.这将需要两个具有相同产品和订单ID的记录. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容