1

我正在向 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 之前,其值如下:

  • 产品 ID = 5
  • 记录 ID = 0
  • 计数 = 1
  • 产品.ProductID = 5
  • Product.CategoryID = 5

保存更改后,cartItem 的值发生了变化(我还注意到传递给方法的原始对象的值发生了变化)。这是之后的值

  • 产品 ID = 7
  • 记录 ID = 9
  • 计数 = 1
  • 产品.ProductID = 7
  • 产品.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 的要求,我的 Cart 和 ShoppingCart 模型的链接位于以下链接:

Rob 提供的调试代码结果:

4

2 回答 2

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

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

于 2013-03-28T14:12:56.860 回答
0

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

这就是你所拥有的:

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

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

在您的情况下,我将创建一个新的构造函数ShoppingCart并使用它而不是您的静态工厂方法:

public ShoppingCart(HttpContextBase context)
{
    ShoppingCartId = GetCartId(context);
}
于 2013-03-28T14:44:19.013 回答