无需详细说明,现在我有两个实体:发票和产品。如果表中的记录总数没有减少,而是添加了一个新表(如果这个判断错误,正确我)
发票代码:
public class Invoice
{
[Key]
public long Id { get; set; }
///Any property
public virtual ICollection<Product> CurrentProducts { get; set; } = new HashSet<Product>();
///Any property
}
产品代码: 任何东西都可以是产品
public class Product
{
[Key]
public int Id { get; set; }
///Any property
public virtual ICollection<Invoice> Invoices { get; set; } = new HashSet<Invoice>();
///Any property
}
商品代码:
public class CatItem
{
[Key]
public int Id { get; set; }
///Any property
public short Quantity { get; set; }
public virtual int ProductId { get; set; }
public virtual Product Product { get; set; }
public virtual long InvoiceId { get; set; }
public virtual Invoice Invoice { get; set; }
///Any property
}
我明白通过 cartItem 做什么更正确,但是没有更好的实现购物车的做法吗?
如果
Product
表应该仅用作发票上的项目列表,那么它可能就足够了,但您至少应该将 Product
表重命名为 InvoicePosition
.
如果您打算在其他地方使用
Product
表,比如列出您商店中的可用产品,那么您肯定想要规范化这些表。您的多对多示例中的 Product
表在这种(以及许多其他)场景中根本不起作用。
在您的多对多示例中,您有多个名称相同但价格不同的产品。对于每张发票,您都需要一个单独的位置。我无法想象它除了用作 InvoicePosition
桌子之外还有什么用途。
如果你想进一步规范你的表格,并使它们更灵活,你可能需要考虑创建一个单独的
Price
表,与
ProductId、当前价格和此类价格可用时的日期范围。看起来基于“苹果”产品,您希望支持给定产品的价格变化。
所以,更灵活一点的数据库方案可能看起来像这样:
public class Invoice {
public long Id { get; set; }
public long CartId { get;set; }
public List<InvoicePosition> Positions { get; set; }
}
public class InvoicePosition {
public long Id { get; set; }
public long InvoiceId { get; set; }
public int CartItemId { get; set; }
public decimal Value { get; set; }
public int Quantity { get; set; }
}
public class Product {
public int Id { get; set; }
public string Name { get; set; }
public AvailableQuantity { get; set; } // should be probably also moved to some kind of a warehouse model
public List<Price> Prices { get; set; }
}
public class Price {
public long Id { get; set; }
public int ProductId { get; set; }
public decimal Value { get; set; }
public DateTimeOffset From { get; set; }
public DateTimeOffset To { get; set; }
}
public class Cart {
public long Id { get; set; }
public List<CartItem> Items { get;set; }
}
public class CartItem {
public long Id { get; set; }
public long CartId { get; set; }
public int ProductId { get; set; }
public long PriceId { get; set; }
public int Quantity { get; set; }
}
我希望,其中大部分都相当容易理解。你可能会有疑问,在
CartItem
内部引用InvoicePosition
而不是简单地引用一个Product
有什么好处?
这并非完全必要,但是,它可以帮助您应用并更轻松地跟踪额外的价格调整因素,例如折扣或特别促销。
并且拥有已订购和已开具发票的历史记录(它们肯定可能不同,例如下订单后仓库中缺少物品)绝对非常有用。