Я пытаюсь сделать обновление в таблице Order_Details базы данных Northwind, используя EF 4.1 (POCO).
Таблица определяется как:
[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();
Я поработал с Google и нашел [это решение] , сказав, что способ сделать это - создать новый экземпляр нового Продукта и связать его со свойством навигации Product_Detail´S Product.
Но, делая это, я получаю еще одно исключение:
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();
Что я могу сделать, чтобы позволить пользователю изменить продукт в элементе Detail? Мне действительно не нравится идея удалить всю запись и воссоздать ее с новым продуктом. Пахнет очень плохо!
Спасибо!