我使用C#编写一个(假设的)应用程序 - 在线商店。
我有一个产品数据库,每个产品都有以下相关信息:
我有4个页面显示已过滤的产品列表。页面显示每种产品的不同信息:
我的问题是,如何设计数据结构以容纳我的所有网页而几乎没有重复?
蛮力方法是为每个页面创建一个类型:
IList<Product>
IList<ProductWithRating>
IList<ProductWithSoldQuantity>
IList<ProductWithRatingAndSoldQuantity>
以后3可以从Product
派生,但由于缺少多重继承,ProductWithRatingAndSoldQuantity
无法从Rating和SoldQuantity产品中获得。
在动态语言中,我只想添加我需要的任何字段并感到高兴。
因此,我可以通过在单独的独角兽中存储额外信息(评级,销售数量)来模拟动态语言方法,例如:
{
IList<Product> Products;
IDictionary<Product, Rating> ProductRatings;
IDictionary<Product, SoldQuantity> ProductSoldQuantities;
}
// is equivalent to
IList<ProductWithRatingAndSoldQuantities>
构建包含所有内容然后传递部分初始化对象的产品结构是不我正在寻找的解决方案。
有什么建议吗?
答案 0 :(得分:1)
为什么Rating
和SoldQuantity
不能为空?或者总是在场,但并不总是在场?
答案 1 :(得分:1)
您可以存储作为属性销售的评级和数量,然后存储表明它们是否存在的布尔值吗?我认为你应该在做作文时使用继承。
答案 2 :(得分:1)
抱歉没有足够的人来回复评论。
您应该拥有一个域对象Product。它将具有不可为空的Name和ProductNumber以及Price,因为您不能拥有那些没有这些东西的产品。
评级应该是可以为空的,因为可能有一个没有评级的产品。无论产品是否具有评级,它仍然是产品。我将离开QuantitySold,因为我实际上不会将其存储为产品的属性,我将拥有Orders和OrderLine集合,并从那些(规范化)计算QuantitySold。但是,如果没有其他集合,您可以将其存储为Product上的字段。如果我要这样做,它将是一个不可为空的整数属性,默认为零。
你只需要一个集合来过滤,这可能是IEnumerable或IQueryable或两者的一些实现,很可能你会选择像Entity Framework这样的东西并且实际上有一个ObjectSet但是我试图保持我的设计不可知我正在使用什么存储方法并对这些接口起作用。
然后,您可以查询单个集合,以确定域模型中的产品上哪些属性为空。语法可能不完美,但Intellisense不会接受,我99%的时间都是VB人。
var productsWithNoSales = Context.Products.Where(p=> p.QuantitySold == 0);
var productsWithNoRating = Context.Products.Where(p=> p.Rating == nothing);
var productsWithNoSalesOrRating = Context.Products.Where(p=> p.QuantitySold == 0).Where(p=> p.Rating == nothing);
这几乎是你所追求的最简洁的域模型。
如果您拥有具有额外属性或不同行为的Product的专用衍生产品,则继承。例如,我自己的系统有一个基本的Product类,以及一个EbayProduct和AmazonProduct实体,它们都从Product继承并且只包含与使用这些站点相关的额外逻辑和属性。我的产品类有大约20个属性 - 大部分都是可空的,因为当我们列出产品时,我们不一定拥有所有可用的信息。在这20个页面中,我在任何一个页面上显示的最多大约是15个。我可能会做类似于您尝试做的事情,因为我使用所描述的确切方法过滤掉尚未准备列出的产品,即过滤缺少字段的我的产品系列。
答案 3 :(得分:0)
您可以指定您正在使用的内容吗?一开始你的“页面”是什么?您的数据存储方法是什么?
这听起来像是在混淆显示数据并存储数据?没有义务仅仅因为它存在而显示数据。
您的对象域几乎肯定只有产品。将设置数据存储以使属性可为空,并检查空值以获取数据。
如果你正在使用像Linq这样的东西,你可以简单地做一些像
这样的事情var productsWithoutRating = Context.Products.Where(p => p.Rating == nothing);
字典的想法,继承和构图都显得有些奇怪。存储一个单独的布尔值,告诉你属性是否存在是混乱的,并且将是一个维护的噩梦 - 只需检查它是否存在即时。