【问题标题】:Entity Framework - Add an item to a list more than once实体框架 - 将一个项目多次添加到列表中
【发布时间】:2014-12-10 12:20:12
【问题描述】:

我正在创建一个实体框架代码优先应用程序,但在尝试多次将实体添加到列表时遇到了问题。

我有以下两个类,它们相互引用以实现多对多关系。

public class Order
{

    public virtual List<OrderItem> OrderItems { get; set; }

}   

public class OrderItem
{

    public virtual List<Order> Orders{ get; set; }

}

这会在我的数据库中创建以下三个表:

Orders
 - OrderId (PK, int)

.

OrderItems
 - OrderItemId (PK, int)

.

OrderOrderItems
 - Order_OrderId (PK,FK,int)
 - OrderItem_OrderItemId (PK,FK,int)

在代码中,我希望执行以下操作:

private void AddOrderItemsTest 
{
    OrderItem orderItem = GetOrderItem(); // gets an existing order item from the DB
    var order = new Order();
    order.OrderItems.Add(orderItem);
    order.OrderItems.Add(orderItem); // add the order item to the list a second time
    context.Orders.Add(order);
}

当它被持久化到数据库时,只有一个 orderItem 实体被添加到列表中。我们在 OrderOrderItems 表中看到 OrderItem_OrderItemId 是一个 PK,因此必须是唯一的。这意味着 EF 以一种不允许将多个相同类型的 orderItem 多次添加到列表中的方式设计表。

是否有我可以添加的数据注释来告诉 EF 允许我将多个相同类型的项目添加到列表中?

【问题讨论】:

  • 这个问题似乎问了同样的问题:stackoverflow.com/questions/7191132/… 这个问题已经存在三年了,所以除非你确定从现在到那时没有任何变化(我们现在在 EF6 上)请做不要将其标记为重复。
  • 将同一项目添加到两次收藏的目的是什么?您如何期望将数据存储在表中? OrderOrderItems 中有多个重复的行或 OrderItemsOrderOrderItems 中有两条不同的记录?
  • @Vladimirs 如果客户想购买两件相同的商品,那么我会将其添加到列表中两次。我希望OrderOrderItems 表中有两个重复的行,但我并不介意 EF 如何实现它!
  • doh.. 出于某种愚蠢的原因,我什至没有费心阅读您的第一条评论(最好将该信息包含在实际问题中)。我相信没有任何改变,因为您仍然需要多对多关系的主键。

标签: entity-framework ef-code-first many-to-many


【解决方案1】:

我认为在您的订单中处理(同一商品的)商品数量的方法不正确。您真的希望将 10000 个重复条目加载到您的 OrderItems 集合中吗?我猜不是。

您需要在OrderOrderItems 表上使用不同的主键,因此建议引入包含OrderItemOrder 数量的新实体:

public class OrderItemDetails
{
    public int OrderItemDetailsId { get; set; }
    public int OrderId { get; set; }
    public int OrderItemId { get; set; }
    public int Amount{ get; set; }

    public virtual Order Order { get; set; }
    public virtual OrderItem OrderItem { get; set; }
}

public class Order
{
    public virtual List<OrderItemDetails> OrderItemDetails { get; set; }
}

public class OrderItem
{
    public virtual List<OrderItemDetails> OrderItemDetails { get; set; }
}

如果您对引入Amount 不满意并且仍然希望每个项目实例都有重复的条目,那绝对没问题,因为您的多对多关系的主键不是OrderIdOrderItemId 的组合但是OrderItemDetailsId

【讨论】:

  • 你在现场 - 这是一个更好的方法来做到这一点。谢谢。
  • 这也设置了一个存储 OrderItem 的“冻结”副本的好地方 - 以管理价格变化等。
猜你喜欢
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
  • 2013-06-03
  • 2023-04-01
  • 1970-01-01
  • 2012-10-28
  • 1970-01-01
相关资源
最近更新 更多