在MVC中,我经常遇到模型设计的问题。大多数情况下,我的所有项目都需要一些要创建、编辑和删除的实体。这些实体中的大多数都有一些共同的属性,如创建日期、修改日期、作者、修改者,在某些情况下,甚至还有更多描述性的属性。正因为如此,我有一个单独的DB表来存储它们。例如,Documents表,我们在其中存储发票、报价单和其他业务文档。我使用的是实体框架v4,我们最终得到的是文档实体。
我如何修改这个实体,或者我要为它创建一个单独的DocumentViewModel类来支持具有公共属性的多种文档类型(因此应该实现某种形式的继承或接口实现)?除了识别不同的文档类型外,我还需要一些类型来拥有不同的数据注释规则(属性)。
例如,文档表有PayDate列。单据类型发票需要提供PayDate,但单据类型报价单不需要。
这是我在使用MVC时反复面临的一个问题,到目前为止,我每次都在以不同的方式处理它,但无法决定如何正确地处理它,以实现最大的应用程序可维护性和开发简易性。
发布于 2010-10-06 06:49:47
您是否考虑过将文档抽象为实体
在DB端,您将拥有包含所有发票/报价/等共享的字段的Documents表。此字段将具有身份PK -例如DocId。
在其他表中,可以存储特定于该文档的其他元数据,并且PK是一个(非标识)字段DocId,它也是Documents表的FK。
在EF端,Documents成为一个抽象实体,其他实体继承自该实体。这允许存在一个很好的OO范例,并使您的代码更加健壮。
我们目前正在使用此方案(EF4/SQL Server)。
你的场景听起来和我们的非常相似--考虑使用抽象类。
编辑
我想在我如何实际实现这个场景中添加更多信息,以使您走上正确的轨道。
作为对你的Q状态的评论,我们对你的领域知之甚少,因此很难发表有见地的意见。就我个人而言,我选择将我的实体抽象,因为某些功能需要在一次点击中返回“混合包”的项目。当然,还有其他方法可以做到这一点(例如存储过程),但这允许在我的UI (顺便说一句,是MVC )和我的服务层之间提供一个流畅的界面。
工作原理是这样的--下面是我如何获得一个single帖子的方法:
// var is strongly-typed to a "Post"
var somePost = repository.FindSingle(10); 下面是我如何获得一个混合包的帖子:
// var is strongly-typed to a "ICollection<Post>".
// "Title" is a property on my "Post" abstract POCO
var mixedBagOfPosts = repository.FindAll<Post>(p => p.Title = "Some Title"); 下面是我如何获得一个“评论”的集合(帖子的子集):
// var is strongly-typed to a "ICollection<Review>"
// "Rating" is a property on my "Review" POCO (derived from Post)
var reviews = repository.FindAll<Review>(r => r.Rating == 5.00);最重要的是我的存储库是用泛型实现的,类型参数确保了类型安全:
ICollection<T> FindAll<T>(Expression<Func<T,bool>> predicate) where T : Post它是这样实现的:
return myContext.Posts.OfType<T>.Where(predicate).ToList();OfType会导致对T(子表)的内部联接,因此只返回这些记录。
当然,我也有一个服务层在我的UI和存储库之间进行协调,但这应该会让您走上正确的道路。
此外,您不必使用整个表达式谓词,我喜欢这一点,因为它最大限度地减少了接口上的方法数量,并为控制器提供了充分的查询能力,同时确保查询延迟到服务层,而不是进一步。
如果你不喜欢这样,你当然可以有常规的参数(字符串标题等)。
正如我所说的,这种架构适合我的域需求,因此它可能不一定适合您的需求,但希望它能给您一些洞察力。
发布于 2010-10-06 06:33:39
您可以在EF模型中多次放置一个表,然后将其重命名为所需的实体。只需从这些列中删除不需要的列。
例如,放入一个文档实体...现在将其重命名为Invoice。现在添加另一个,并将其命名为Quotation...在报价上,单击PayDate并按delete键。你可以自定义这些你想要的!您可以对其他ORM执行相同的操作,只是需要多做一点工作。使用NHibernate,您将手动创建模型,然后将它们映射到同一个表,但只映射您需要的内容。
https://stackoverflow.com/questions/3868007
复制相似问题