首页 / C# / c# – 使用EF更新PK时出错
c# – 使用EF更新PK时出错
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 使用EF更新PK时出错,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3723字,纯文字阅读大概需要6分钟。
内容图文
我正在尝试使用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, ErrorMessageResourceType = typeof(Messages), 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, ErrorMessageResourceType = typeof(Messages), 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);
detail.Quantity = short.Parse(e.NewValues["Quantity"] as string, CultureInfo.CurrentCulture);
detail.Discount = float.Parse(e.NewValues["Discount"] 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的记录.
内容总结
以上是互联网集市为您收集整理的c# – 使用EF更新PK时出错全部内容,希望文章能够帮你解决c# – 使用EF更新PK时出错所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。