繁体   English   中英

使用 EF 更新 PK 时出错

[英]Error when updating PK with EF

我正在尝试使用 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 项目时,出现异常:

The property 'ProductID' is part of the object's key information and cannot be modified.

代码是:

        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 的产品导航属性。

但这样做我得到另一个例外:

A referential integrity constraint violation occurred: A primary key property that is a part of referential integrity constraint cannot be changed when the dependent object is Unchanged unless it is being set to the association's principal object. The principal object must be tracked and not marked for deletion.

修改后的代码:

        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 的记录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM