购物车实现 - 是否可以对每个 CRUD 操作进行服务器调用?

Cart Implementation - is it ok to do a server call on each CRUD operation?

提问人:A7med 提问时间:10/22/2023 最后编辑:A7med 更新时间:10/29/2023 访问量:30

问:

我正在观看有关使用 .Net Core 的电子商务网站的教程 - 该项目的类型为 Web Assembly Blazor,我检查了 .NET CORE 托管,因此该项目被喷到客户端、服务器和剪切。

购物车模型由 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();
}

我的问题是:

这可以/实用吗?在每次购物车更改/更新时都调用服务器?

我的建议:

如果我们可以在部分末尾或仅在结帐时更新服务器端,但我不知道这是否可能

C# asp.net 实体框架 设计模式 电子商务

评论


答:

0赞 Steve Py 10/23/2023 #1

作为 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);

如果服务器调用验证数量是否为有效值(即非负数),则检索购物车产品,验证库存水平,并更新购物车产品的数量。这可能是原始方法会做的事情,但它不需要整个模型来做到这一点,并且可能会有更新数量以外的值的诱惑。