ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 使用EF更新PK时出错

2019-07-10 02:04:45  阅读:196  来源: 互联网

标签:c asp-net entity-framework ef-code-first poco


我正在尝试使用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,asp-net,entity-framework,ef-code-first,poco
来源: https://codeday.me/bug/20190710/1419398.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有