简体   繁体   中英

Strange behavior in Entity Framework with a list

I have an winforms order taking app for a restaurant. On startup I read the list of products available as this:

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

When the user clicks the button corresponding to a menu Item, I identify the product to be added to the order like this:

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
};

Here is the OrderItem entity:

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; }
}

After saving the order, some strange things happen (for me anyway): The product in the list changes its Id, as if it is a new product, with the same attributes. Also after context.SaveChanges() in the database I will have 2 rows of the same product.

Anyone can point out what I am doing wrong?

When you Add the Order , the Product is also changed to Added . You can simply prevent this by removing the assignment

Product = product

It is enough to set ProductId .

You have obtained the list of products as NoTracking. But then you assign it to the product in the orderitem, effectively pulling the object back in. If you just leave out that statement and do this instead

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
};

then it will work ok.

After reading the question @Jehof mentioned, I solved it by reattaching the products to the new context in which SaveChanges() occurs:

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

Thanks for your comments!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM