MVC Entity Framework:设置唯一默认收货地址的实现方案
解决同一用户多个默认收货地址的问题
这个场景我之前也遇到过,核心就是要确保同一时刻用户只有一个默认收货地址。我们只需要在保存目标地址前,先把该用户所有地址的IsDefaultShippingAddress设为false,再把当前选中的地址设为true就行。下面给你两种实用方案,你可以根据业务场景选:
方案1:Entity Framework 实体操作(适合小数据量)
这种方式逻辑直观,代码可读性强,适合用户地址数量不多的情况:
// POST: /Manage/EditShippingAddress [HttpPost] [ValidateAntiForgeryToken] public ActionResult EditShippingAddress([Bind(Include = "ID,UserID,IsDefaultShippingAddress,ShippingAddressCompanyName,ShippingAddressFirstName,ShippingAddressLastName,ShippingAddressAdditional,ShippingAddressStreet,ShippingAddressNumber,ShippingAddressZIP,ShippingAddressCity,ShippingAddressState,ShippingAddressCountry,ShippingInstructions,UpdatedLatitude,UpdatedLongitude,UpdatedLocation")] ShippingAddresses model) { var userID = User.Identity.GetUserId(); DateTime nowUTC = DateTime.Now.ToUniversalTime(); DateTime nowLocal = DateTime.Now.ToLocalTime(); ViewBag.Personalization = UserManager.FindById(userID).FirstName.ToString(); // 安全校验:确保当前操作的地址属于登录用户,防止越权 if (model.UserID != userID) { ModelState.AddModelError("", "无权修改该地址"); return View(model); } if (ModelState.IsValid) { // 第一步:将该用户所有收货地址的默认状态批量设为false var userAddresses = DATADB.ShippingAddresses.Where(a => a.UserID == userID); foreach (var address in userAddresses) { address.IsDefaultShippingAddress = false; } // 第二步:把当前操作的地址设为默认 model.IsDefaultShippingAddress = true; DATADB.Entry(model).State = System.Data.Entity.EntityState.Modified; // 一次性提交所有更改到数据库 DATADB.SaveChanges(); return RedirectToAction("ShippingAddresses"); } return View(model); }
方案2:直接执行SQL语句(适合大数据量,效率更高)
如果用户地址数量较多,逐个更新实体的效率会偏低,这时用原生SQL批量更新能减少数据库交互次数,提升性能:
// POST: /Manage/EditShippingAddress [HttpPost] [ValidateAntiForgeryToken] public ActionResult EditShippingAddress([Bind(Include = "ID,UserID,IsDefaultShippingAddress,ShippingAddressCompanyName,ShippingAddressFirstName,ShippingAddressLastName,ShippingAddressAdditional,ShippingAddressStreet,ShippingAddressNumber,ShippingAddressZIP,ShippingAddressCity,ShippingAddressState,ShippingAddressCountry,ShippingInstructions,UpdatedLatitude,UpdatedLongitude,UpdatedLocation")] ShippingAddresses model) { var userID = User.Identity.GetUserId(); DateTime nowUTC = DateTime.Now.ToUniversalTime(); DateTime nowLocal = DateTime.Now.ToLocalTime(); ViewBag.Personalization = UserManager.FindById(userID).FirstName.ToString(); if (model.UserID != userID) { ModelState.AddModelError("", "无权修改该地址"); return View(model); } if (ModelState.IsValid) { // 第一步:用SQL批量重置该用户所有地址的默认状态 string updateSql = "UPDATE ShippingAddresses SET IsDefaultShippingAddress = 0 WHERE UserID = @userID"; DATADB.Database.ExecuteSqlCommand(updateSql, new System.Data.SqlClient.SqlParameter("@userID", userID)); // 第二步:设置当前地址为默认并保存 model.IsDefaultShippingAddress = true; DATADB.Entry(model).State = System.Data.Entity.EntityState.Modified; DATADB.SaveChanges(); return RedirectToAction("ShippingAddresses"); } return View(model); }
额外提醒
- 别忘加用户身份校验,也就是
model.UserID != userID的判断,不然可能被恶意用户钻空子修改他人地址。 - 如果是新增地址时设置默认,逻辑也是一样的:先重置该用户所有地址的默认状态,再把新地址设为默认保存即可。
内容的提问来源于stack exchange,提问作者Ken-F
相关产品推荐
相关产品推荐

