MVC Music Store 在线音乐商店示例分析(6)ShoppingCart

在Models文件夹中,ShoppingCart.cs文件中的类是购物车类。

该类定义了购物车的一些属性。该类相对来说稍微复杂点。

添加注释后具体代码如下:

1 /// <summary>
2 /// 购物车
3 /// 分布类
4 /// </summary>
5   public partial class ShoppingCart
6 {
7 /// <summary>
8 /// 音乐商店实体
9 /// 用于操作购物车时,对应数据库的具体数据操作。
10 /// (提取商品信息、保存订单等)
11 /// </summary>
12   MusicStoreEntities storeDB = new MusicStoreEntities();
13
14 /// <summary>
15 /// 购物车编号
16 /// </summary>
17   string ShoppingCartId { get; set; }
18
19 /// <summary>
20 /// 购物车会话编号
21 /// </summary>
22   public const string CartSessionKey = "CartId";
23
24 /// <summary>
25 /// 获取购物车
26 /// 静态方法
27 /// 从请求的上下文的Cookies中保存的购物车编号获取对应的购物车信息
28 /// </summary>
29 /// <param name="context">HTTP 请求上下文</param>
30 /// <returns>返回购物车</returns>
31   public static ShoppingCart GetCart(HttpContextBase context)
32 {
33 var cart = new ShoppingCart();
34 cart.ShoppingCartId = cart.GetCartId(context);
35 return cart;
36 }
37
38
39 // Helper method to simplify shopping cart calls
40   /// <summary>
41 /// 获取购物车
42 /// 静态方法
43 /// 从ASP.NET MVC的控制器的请求上下文中获取购物车信息
44 /// </summary>
45 /// <param name="controller">控制器</param>
46 /// <returns>返回购物车</returns>
47   public static ShoppingCart GetCart(Controller controller)
48 {
49 return GetCart(controller.HttpContext);
50 }
51
52 /// <summary>
53 /// 购物车添加内容
54 /// </summary>
55 /// <param name="album">相册</param>
56 public void AddToCart(Album album)
57 {
58 // Get the matching cart and album instances
59 //从音乐商店实体中获取匹配车和专辑实例
60 var cartItem = storeDB.Carts.SingleOrDefault(c => c.CartId == ShoppingCartId && c.AlbumId == album.AlbumId);
61
62 if (cartItem == null)
63 {
64 // Create a new cart item if no cart item exists
65 //当购物车项不存在的情况下,创建一个新的购物车项
66 cartItem = new Cart
67 {
68 AlbumId = album.AlbumId,
69 CartId = ShoppingCartId,
70 Count = 1,
71 DateCreated = DateTime.Now
72 };
73
74 storeDB.Carts.Add(cartItem);
75 }
76 else
77 {
78 // If the item does exist in the cart, then add one to the quantity
79 //如果该项内容在购物车中存在,则该项数量增加1
80 cartItem.Count++;
81 }
82
83 // Save changes
84 //通过音乐商店实体保存所做的修改
85 storeDB.SaveChanges();
86 }
87
88 /// <summary>
89 /// 移除购物车指定内容
90 /// </summary>
91 /// <param name="id">记录编号</param>
92 /// <returns>剩余数量</returns>
93 public int RemoveFromCart(int id)
94 {
95 // Get the cart
96 // 通过音乐商店实体获取购物车中指定的购物项目
97 var cartItem = storeDB.Carts.Single(
98 cart => cart.CartId == ShoppingCartId
99 && cart.RecordId == id);
100
101 //当前购物项剩余数量默认为0
102 int itemCount = 0;
103
104 if (cartItem != null)
105 {
106 if (cartItem.Count > 1)
107 {
108 //当该购物项数量大于1时,则将该项内容减1
109 cartItem.Count--;
110 //设置当前购物项剩余数量
111 itemCount = cartItem.Count;
112 }
113 else
114 {
115 //否则通过音乐商店实体,在购物车中移除该购物项
116 storeDB.Carts.Remove(cartItem);
117 }
118
119 // Save changes
120 //通过音乐商店实体保存所做的修改
121 storeDB.SaveChanges();
122 }
123 //当该购物项还有剩余项时,返回当前剩余数量,否则将返回0
124 return itemCount;
125 }
126
127 /// <summary>
128 /// 清空购物车
129 /// </summary>
130 public void EmptyCart()
131 {
132 //获取当前购物车编号下购物车中所有项
133 var cartItems = storeDB.Carts.Where(cart => cart.CartId == ShoppingCartId);
134
135 //移除所有项
136 foreach (var cartItem in cartItems)
137 {
138 storeDB.Carts.Remove(cartItem);
139 }
140
141 // Save changes
142 //通过音乐商店实体保存所做的修改
143 storeDB.SaveChanges();
144 }
145
146 /// <summary>
147 /// 获取购物车中项目
148 /// </summary>
149 /// <returns>返回购物车中项目列表</returns>
150 public List<Cart> GetCartItems()
151 {
152 //获取当前购物车编号下购物车中所有项
153 return storeDB.Carts.Where(cart => cart.CartId == ShoppingCartId).ToList();
154 }
155
156 /// <summary>
157 /// 获取购物车中商品数量
158 /// </summary>
159 /// <returns>购物车中商品数量</returns>
160 public int GetCount()
161 {
162 // Get the count of each item in the cart and sum them up
163 // 获取购物车中每项的数量,并计算总数。
164 // int? 如果有值则返回实际值,没有值则返回null
165 int? count = (from cartItems in storeDB.Carts
166 where cartItems.CartId == ShoppingCartId
167 select (int?)cartItems.Count).Sum();
168
169 // Return 0 if all entries are null
170 // 如果所有项都为空则返回0
171 //?? 运算符称为 null 合并运算符,用于定义可以为 null 值的类型和引用类型的默认值。
172 // 如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数。
173 return count ?? 0;
174 }
175
176 /// <summary>
177 /// 获取总价
178 /// </summary>
179 /// <returns>购物车总价</returns>
180 public decimal GetTotal()
181 {
182 // Multiply album price by count of that album to get the current price for each of those albums in the cart
183 //sum all album price totals to get the cart total
184 // 每个购物项的数量*单价得到该项总价之后再计算所有项的总价。
185 decimal? total = (from cartItems in storeDB.Carts
186 where cartItems.CartId == ShoppingCartId
187 select (int?)cartItems.Count * cartItems.Album.Price).Sum();
188 // total总价有数据则返回实际值,否则返回0
189 return total ?? decimal.Zero;
190 }
191
192 /// <summary>
193 /// 创建订单
194 /// </summary>
195 /// <param name="order">订单</param>
196 /// <returns>返回数据库中订单编号</returns>
197 public int CreateOrder(Order order)
198 {
199 //订单总价
200 decimal orderTotal = 0;
201
202 //获取购物车中所有商品项目
203 var cartItems = GetCartItems();
204
205 // Iterate over the items in the cart, adding the order details for each
206 // 遍历购物车中所有项,用于添加订单的每条详情
207 foreach (var item in cartItems)
208 {
209 var orderDetails = new OrderDetail
210 {
211 AlbumId = item.AlbumId,
212 OrderId = order.OrderId,
213 UnitPrice = item.Album.Price,
214 Quantity = item.Count
215 };
216
217 // Set the order total of the shopping cart
218 //累加每项总价以便计算购物车的总价
219 orderTotal += (item.Count * item.Album.Price);
220 }
221
222 // Set the order's total to the orderTotal count
223 // 赋值订单总价
224 order.Total = orderTotal;
225
226 // Save the order
227 //通过音乐商店实体保存订单
228 storeDB.SaveChanges();
229
230 // Empty the shopping cart
231 // 清空购物车,以便下次使用
232 EmptyCart();
233
234 // Return the OrderId as the confirmation number
235 // 返回订单编号,用于订单确认号
236 return order.OrderId;
237 }
238
239
240 // We're using HttpContextBase to allow access to cookies.
241 /// <summary>
242 /// 获取购物车编号
243 /// 我们使用HTTPContextBase来允许访问cookies来得到编号
244 /// </summary>
245 /// <param name="context">HTTP请求上下文</param>
246 /// <returns></returns>
247 public string GetCartId(HttpContextBase context)
248 {
249
250 if (context.Session[CartSessionKey] == null)
251 {
252 // 请求上下文的当前会话中没有购物车编号的情况下
253 if (!string.IsNullOrWhiteSpace(context.User.Identity.Name))
254 {
255 //当前用户登录的情况下
256 //设置购物车编号为当前用户名
257 context.Session[CartSessionKey] = context.User.Identity.Name;
258 }
259 else
260 {
261 // 用户没有登录的情况下
262 // Generate a new random GUID using System.Guid class
263 // 生成一个全局唯一标识符
264 Guid tempCartId = Guid.NewGuid();
265
266 // Send tempCartId back to client as a cookie
267 // 将该改标识符作为临时购物车编号保存到当前会话当中,
268 // 该会话会将该编号保存到客户端的Cookie中。
269 context.Session[CartSessionKey] = tempCartId.ToString();
270 }
271 }
272
273 return context.Session[CartSessionKey].ToString();
274 }
275
276 // When a user has logged in, migrate their shopping cart to
277 // be associated with their username
278 /// <summary>
279 /// 迁移购物车
280 /// 当用户登录时,将用户登录之前的购物车信息,迁移到登录后的购物车中。
281 /// </summary>
282 /// <param name="userName">用户名</param>
283 public void MigrateCart(string userName)
284 {
285 // 提取购物车中的购买项
286 var shoppingCart = storeDB.Carts.Where(c => c.CartId == ShoppingCartId);
287
288 // 将所有购买项的购物车编号更换为用户名。
289 foreach (Cart item in shoppingCart)
290 {
291 item.CartId = userName;
292 }
293 //保存数据
294 storeDB.SaveChanges();
295 }
296 }

  其中获取购物车方法GetCart重载了两个,一个使用HttpContextBase来获取购物车信息,一个使用Controller来调用上面使用HttpContextBase重载方法来获取购物车信息。这种做法可以通用将来使用HTTPContext和使用控制器的情况,非常方便。

  AddToCart方法用于将来添加新项目到购物车中。该方法中做了判断,可以添加重复项目,每次可以多加一个。但没有可以添加指定数量的方式。如果将来在购物车中要添加指定数量时,这里要使用这个类的话,就比较麻烦了,就需要重复调用AddToCart方法,这样每次都要先查出该购买项,然后判断,然后再增1,再保存,依次循环。如果出现意外的话,那么就不好处理了。这里要提供将来在界面中可以添加指定数量的功能的话,就应该再重构一下该方法。

  RemoveFromCart方法用于在购物车中移除项,同样的每次也只操作一项。如果我要移除这个购物内容话,而当前数量为10的话,岂不是要调用10次这个方法,界面点击10次?我认为这里应该重构一个移除项方法。

  EmptyCart方法是清空购物车、GetCartItems是获取购物车中的购买项列表,这两个方法都简单,没什么好说的。除此之外还提供了GetCount获取购物车商品数量、GetTotal获取购物车总价、CreateOrder创建订单(将购物车的购买项添加到订单以及订单详细中去)这几个方法。

  

  GetCartId获取购物车编号,这里考虑了用户登录与没有登录的情况下处理。登录了就使用用户名作为购物车的标识符,匿名用户的话创建了一个临时的全局唯一标识符来作为购物车标识符。同时还提供了MigrateCart方法用来将匿名用户的购物车迁移到登录用户中去的方法。这个方法非常简单,就是将购物车的标识符修改为用户名作为标识符。

原文地址:https://www.cnblogs.com/stevenhqq/p/1969757.html