【问题标题】:Linq to SQL ForeignKeyReferenceAlreadyHasValueExceptionLinq to SQL ForeignKeyReferenceAlreadyHasValueException
【发布时间】:2011-12-09 02:07:33
【问题描述】:

我查看了几个线程,但没有找到适合我目的的解决方案 (至少我不明白我该如何实现它)

我有一个 WCF 服务,它使用 Linq to SQL 来检索、更新和删除我的 SQL Server 上的对象。

我创建了一个简单的关系数据库,它有一个 客户和订单之间的一对多关系, Order 和 OrderDetails 之间的一对多关系,

现在 My Orders 有一个 CustomerID 的外键,OrderDetails 有一个 Order ID 的外键。

但是 OrderDetails 还包含 Products 表中 ProductID 的 FK。

基本上我现在要做的是使用 OrderID 修改 OrderDetails 并使用 ProductID 添加另一个产品。

虽然我一直收到 ForeignKeyReferenceAlreadyHasValueException,但我遇到了问题

我写了这个,我知道这是完全错误的,但当时我不知道(我对 SQL、Linq to SQL 等完全陌生)我不能这样做。

            OrderDetail item = new OrderDetail();                
            item.OrderID = orderItem.OrderID;
            item.ProductID = orderItem.ProductID;
            item.ProductQuantity = orderItem.ProductQuantity;                              
            jacksDB.OrderDetails.InsertOnSubmit(item);
            jacksDB.SubmitChanges();

我读到我必须使用类似这样的通用代码行来绘制实体或沿着这些线绘制的东西

            var order = jacksDB.Orders.Single(o => o.OrderID == orderItem.OrderID);
            var orderDetail = order.OrderDetails.Single(o => o.OrderID ==    orderItem.OrderID);
            orderDetail.ProductID = orderItem.ProductID;
            orderDetail.ProductQuantity = orderItem.ProductQuantity;
            orderDetail.Discount = orderItem.Discount;
            jacksDB.OrderDetails.InsertOnSubmit(orderDetail);
            jacksDB.SubmitChanges();

也许有人可以展示一下,如果不是太多,请解释一下我如何正确地使用现有的 OrderID (FK) 将新的 OrderDetail 记录插入到我的 OrderDetails 表中,以便“编辑和添加/将产品删除到现有订单”

提前感谢您的帮助

约翰

【问题讨论】:

  • 也许您可以发布创建表所需的 SQL,包括主键和外键?

标签: c# sql sql-server-2008 linq-to-sql


【解决方案1】:

好的,所以你得到了这个错误,

http://msdn.microsoft.com/en-us/library/system.data.linq.foreignkeyreferencealreadyhasvalueexception.aspx

ForeignKeyReferenceAlreadyHasValueException

链接说明了这一点,

表示在实体已加载时尝试更改外键时发生的错误。

我认为您需要做的是加载您正在谈论的订单,它将有一个与之关联的 OrderDetails 列表。如果要删除其中一个引用,则需要从 OrderDetails 列表中删除 OrderDetail。

我认为你需要做这样的事情,

using (DataClasses1DataContext context = new DataClasses1DataContext())
{
    Customer customer = context.Customers.Where(x => x.CustomerID == 1).Single();
    Order order = new Order();
    // set some order fields here
    customer.Orders.Add(order);

    OrderDetail orderDetail = new OrderDetail();
    order.OrderDetails.Add(orderDetail);

    orderDetail.Product = context.Products.Where(x => x.ProductID == 2).Single();
    orderDetail.ProductID = orderDetail.Product.ProductID;

    context.SubmitChanges();
}

尝试不使用 InsertOnSubmit,但仍保留 SubmitChanges。我建议因为您已经通过设置添加记录,

order.OrderDetails.Add(orderDetail);

所以你可能不需要再次插入它。

【讨论】:

  • 谢谢彼得,我想要实现的是添加一个新的 OrderDetails 记录,其中包含现有的 OrderID,例如 OrderID = 7;当我创建一个包含 5 个产品的订单时,我想将第 6 个产品添加到已创建的订单中
  • 那么您是否尝试过查看订单记录?它是否有一个 OrderDetails 属性,它是一个项目列表。将 OrderDetails 添加到其中。
  • OrderDetail 和 Product 有一对一的关系吗?您还需要将 OrderDetails.Product 记录设置为 Product。我只是凭感觉来的,哈哈。
  • 这应该是我现在的建议,我不确定您是否必须设置 ProductID 以及 Product,但您可能需要这样做。
  • 没问题。很高兴能提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多