带有列表的Entity Framework中的奇怪行为

时间:2015-02-19 06:51:18

标签: c# entity-framework

我有一个winforms订单正在为一家餐馆申请。在启动时,我阅读了可用的产品列表:

var products = context.Products.AsNoTracking().OrderBy(p => p.Id).ToList();

当用户点击菜单项对应的按钮时,我会识别要添加到订单中的产品,如下所示:

var product = products.FirstOrDefault(p => p.Id == menuItem.ProductId);
var orderItem = new OrderItem
{
    ProductId = product.Id,
    Quantity = 1,
    UnitPrice = product.Price,
    ListValue = 1 * product.Price,
    Product = product
};

这是OrderItem实体:

public partial class OrderItem
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public decimal Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal TotalValue { get; set; }

    public Order Order { get; set; }
    public Product Product { get; set; }
}

保存订单后,会发生一些奇怪的事情(对我而言):列表中的产品会更改其ID,就好像它是新产品一样,具有相同的属性。在数据库中context.SaveChanges()之后,我将有2行相同的产品。

任何人都可以指出我做错了什么?

3 个答案:

答案 0 :(得分:1)

当您Add Order时,Product也会更改为Added。您可以通过删除作业来阻止此操作

Product = product

设置ProductId就足够了。

答案 1 :(得分:1)

您已获得NoTracking产品列表。 但是然后你将它分配给orderitem中的产品,有效地将对象拉回来。 如果你只是遗漏那个陈述而不是这样做

var product = products.FirstOrDefault(p => p.Id == menuItem.ProductId);
var orderItem = new OrderItem
{
    ProductId = product.Id,
    Quantity = 1,
    UnitPrice = product.Price,
    ListValue = 1 * product.Price,
    //Product = product don't do this
};

然后它会正常工作。

答案 2 :(得分:0)

在阅读@Jehof提到的问题之后,我通过将products重新连接到SaveChanges()发生的新上下文来解决它:

products.ForEach(p => context.Products.Attach(p));
context.SaveChanges();

感谢您的评论!