我正在观看有关使用 .Net Core 的电子商务网站的教程 - 该项目的类型为 Web Assembly Blazor 并且我检查了 .NET CORE 托管,因此该项目对客户端、服务器和剪裁感到不满。
Cart 模型由 CartId、ProductId 和 UserId 组成。
public class CartItem
{
public int CartId { get; set; }
public int UserId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; } = 1;
}
当讲师实现购物车模型时,他仅在客户端使用本地存储,并通过一个服务器调用获取产品详细信息
服务器服务
public interface ICartService
{
Task<ServiceResponse<List<CartProductResponse>>> GetCartProducts(List<CartItem> cartItems);
}
客户服务
public interface ICartService
{
event Action OnChange;
Task AddToCart(CartItem cartItem);
Task<List<CartItem>> GetCartItems();
Task<List<CartProductResponse>> GetCartProducts();
Task RemoveProductFromCart(int productId, int productTypeId);
Task UpdateQuantity(CartProductResponse product);
}
所以到目前为止,我的布莱恩一切都有意义,所有 CURD 操作都主要在客户端。但是当他把本地存储迁移到数据库之后。 CRUD操作都在客户端和服务器端
服务器服务
public interface ICartService
{
Task<ServiceResponse<List<CartProductResponse>>> GetCartProducts(List<CartItem> cartItems);
Task<ServiceResponse<List<CartProductResponse>>> StoreCartItems(List<CartItem> cartItems);
Task<ServiceResponse<int>> GetCartItemsCount();
Task<ServiceResponse<List<CartProductResponse>>> GetDbCartProducts();
Task<ServiceResponse<bool>> AddToCart(CartItem cartItem);
Task<ServiceResponse<bool>> UpdateQuantity(CartItem cartItem);
Task<ServiceResponse<bool>> RemoveItemFromCart(int productId, int productTypeId);
}
客户服务
public interface ICartService
{
event Action OnChange;
Task AddToCart(CartItem cartItem);
Task<List<CartProductResponse>> GetCartProducts();
Task RemoveProductFromCart(int productId, int productTypeId);
Task UpdateQuantity(CartProductResponse product);
Task StoreCartItems(bool emptyLocalCart);
Task GetCartItemsCount();
}
我的问题是:
这样可以/实用吗?每次购物车更改/更新时都会调用服务器吗?
我的建议:
如果我们可以在部分结束或仅在结账时更新服务器端,但我不知道这是否可能
问 5 个人,你可能会得到 5 个不同的答案。这实际上并不是一个 StackOverflow 类型的问题,因为 SO 专注于与实现相关的问题。 (即为什么这不起作用?)
作为 EF 的一般规则,每次操作都访问数据库是否存在问题?不。数据库是事实的来源,过度假设我们可以避免被认为是“昂贵”的数据库调用,然后将一些累积的状态一次性转储到数据库中,这可能是危险的。这种方法的最大问题是带有数据库的系统很少被单独修改。从特定用户获取当前状态的时间到他们提交这些更改的时间之间,数据状态可能会发生变化。这两个事件之间经过的工作/时间越多,您处理数据状态冲突的可能性就越大(如果您确实查找它们),或者覆盖状态和状态更改丢失的可能性就越大。目标是提高状态和结构化操作的效率,使其大小达到所需的大小。所以是的,我建议像您概述的那样进行多个原子调用,而不是编写一个执行以下操作的服务:
// IMO bad design...
public interface ICartService
{
Cart GetCart(cartId);
void SaveCart(Cart cart);
}
...我们依靠客户端代码/时间来管理修改购物车以最大程度地减少潜在的数据库调用。像这样的设计可能会出很多问题。
要考虑的另一个目标是在服务器和客户端之间传递数据并返回时构造调用以传递最小可行数据。所以这样调用:
Task RemoveProductFromCart(int productId, int productTypeId);
真的很好。我们只将两个整数传递给服务器。服务器验证或忽略无效请求。
这样的事情:
Task UpdateQuantity(CartProductResponse product);
没那么多,这看起来像是一个表单 POST,因为之前的操作返回了 CartProductResponse。如果用户在编辑购物车中的产品时通常所能做的就是更新数量,那么:
Task UpdateQuantity(int cartProductId, int quantity);
服务器调用验证数量是否为有效值(即非负)时,将检索购物车产品、验证库存水平并更新购物车产品的数量。这可能是原始方法所做的,但它不需要整个模型来做到这一点,并且可能存在更新数量以外的值的诱惑。