为什么我的DBContext.SaveChanges()方法更改了我正在添加的对象的值?

时间:2013-03-28 14:09:47

标签: c# asp.net-mvc asp.net-mvc-3 dbcontext

我正在向DBContext集合添加一个对象。在将它保存到集合之前,该对象中的变量都是正确的,在保存之后,并使用VS2012具有的调试工具查看DBContext集合内部,我注意到对象内部的所有值都发生了变化。以下是相关代码:

public class AdmissionsStoreEntities : DbContext
{
    public DbSet<Cart> Carts { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }
}

public void AddToCart(Product product)
{
    // Get the matching cart and product instances
    var cartItem = storeDB.Carts.SingleOrDefault(
        c => c.CartId == ShoppingCartId
        && c.ProductId == product.ProductId);

    if (cartItem == null)
    {
        // Create a new cart item if no cart item exists
        cartItem = new Cart
        {
            ProductId = product.ProductId,
            Product = product,
            CartId = ShoppingCartId,
            Count = 1,
            DateCreated = DateTime.Now
        };

        // storeDB is my AdmissionsStoreEntities() object.
        storeDB.Carts.Add(cartItem);
    }
    else
    {
        // If the item does exist in the cart, then add one to the quantity.
        cartItem.Count++;
    }

    // Save Changes (where the changes occur)
    storeDB.SaveChanges();
}

例如,在将cartItem对象保存到storeDB.Carts之前,值如下:

  • ProductId = 5
  • RecordId = 0
  • Count = 1
  • Product.ProductID = 5
  • Product.CategoryID = 5

保存更改后,cartItem的值会发生变化,(我还注意到传入方法的原始对象的值已更改)。以下是值

  • ProductId = 7
  • RecordID = 9
  • Count = 1
  • Product.ProductID = 7
  • Product.CategoryID = 7

为什么会这样?如果需要,我可以提供更多代码。

根据要求,这就是我获取ShoppingCartId的方式。

public ActionResult AddToCart(int id)
    {
        // Retrieve the product from our ViewData object that holds all current  data        in the SharePoint list
        var addedProduct = ((List<Product>)ViewData["AllProducts"]).Find(x => x.ProductId == id);

        // Get our cart instance.
        var cart = ShoppingCart.GetCart(this.HttpContext);

        // Add product to cart.
        cart.AddToCart(addedProduct);

        // Go back to the main store page for more shopping
        return RedirectToAction("Index");
    }

public static ShoppingCart GetCart(HttpContextBase context)
    {
        var cart = new ShoppingCart();
        cart.ShoppingCartId = cart.GetCartId(context);
        return cart;
    }

public string GetCartId(HttpContextBase context)
    {
        if (context.Session[CartSessionKey] == null)
        {
            if (!string.IsNullOrWhiteSpace(context.User.Identity.Name))
            {
                context.Session[CartSessionKey] = context.User.Identity.Name;
            }
            else
            {
                Guid tempCartId = Guid.NewGuid();

                context.Session[CartSessionKey] = tempCartId.ToString();
            }
        }
        return context.Session[CartSessionKey].ToString();
    }

根据Rob的要求,我的购物车和ShoppingCart模型的链接位于以下链接:

Rob提供的调试代码的结果:

2 个答案:

答案 0 :(得分:1)

修改

尝试删除Product = product

if (cartItem == null)
    {
        // Create a new cart item if no cart item exists
        cartItem = new Cart
        {
            ProductId = product.ProductId,
            //Product = product,
            CartId = ShoppingCartId,
            Count = 1,
            DateCreated = DateTime.Now
        };

        // storeDB is my AdmissionsStoreEntities() object.
        storeDB.Carts.Add(cartItem);
    }

设置产品ID应该可以解决问题,您不需要实际的对象。

答案 1 :(得分:0)

我不确定,但我认为这可能是在多线程环境(ASP.NET)中使用静态工厂方法的副作用。

这是你得到的:

public static ShoppingCart GetCart(HttpContextBase context)
{
    var cart = new ShoppingCart();
    cart.ShoppingCartId = cart.GetCartId(context);
    return cart;
}

您获得了cart.GetCartId(context)的不同值,具体取决于您传递的context,但由于这是一个静态方法,因此您只能获得该方法及其内部变量的一个副本。如果两个人同时调用它,您可以将cart.GetCartId()的值分配给不同于预期的购物车。

在你的情况下,我会为ShoppingCart创建一个新的构造函数,并使用它代替你的静态工厂方法:

public ShoppingCart(HttpContextBase context)
{
    ShoppingCartId = GetCartId(context);
}