2014-10-09 25 views
0

我有一个包含服务层的MVC项目。服务类将db实体对象返回给我用来构建传递给Views的模型的控制器。通过这种方式,我的服务层不了解模型,我试图保持这种模式。MVC保持模型退出服务层 - 并非总是可行

一个典型的服务层方法将返回的IQueryable如:

public IQueryable<Store> GetAll() 
{ 
    return _context.Set<Store>(); 
} 

但是有时我需要从说,在没有DB关系存在和2个分贝实体返回数据,因为该服务层不能返回一个匿名类型,我最终返回了一个模型,我并不高兴。

的一个例子是:

public IEnumerable<CashDrawerModel> GetTillList(int? storeId) 
{ 
var query = from c in _context.Set<CashDrawer>() 
    where c.StoreId == storeId || storeId == null 
    join cd in _context.Set<CashDrawerActivity>() on c.Id equals cd.CashDrawerId into joinedT 
    from j in joinedT.DefaultIfEmpty() 
    group joinedT by c into g 
    select new CashDrawerModel 
    { 
     ... 

我怎样才能避免这种情况?我是否有必要担心保持这种分离,还是实际上表明数据库设计不佳并需要重构?

回答

0

我不认为这是一个糟糕的数据库设计,而且在将数据传递给视图之前必须查询多个数据库实例时,这是非常常见的情况。有时,读写操作之间的差异非常大,以至于遵循Command Query Separation原则是一个好主意。

所以,如果我是你,我会做到以下几点:

  1. 需要时阅读模型添加到您的服务层。请注意,它们与视图模型无关。如上所述,读取结果由几个db实体组成时,应该使用它们。

  2. 添加相应的视图模型并在控制器中执行服务层读取模型和视图模型之间的映射。这样,您可以将服务层与演示文稿分开。如果视图模型结果是服务层读取模型的精确副本,则可以跳过在此情况下创建视图模型,并将读取模型传递给视图。但是,如果您需要添加一些与服务层无关的特定于UI的数据,则必须创建视图模型并进行映射。

  3. 拿出一个很好的命名对照。我更喜欢XXXReadModel作为服务层读取模型,而XXXViewModel作为表示层视图模型。

因此,如果按照上面描述的步骤,您应该有CashDrawerReadModel这是服务层的一部分。然后你应该有CashDrawerViewModel这是一个演示层视图模型,并在控制器中进行两者之间的映射。如果与CashDrawerReadModel相同,并且在视图中只使用CashDrawerReadModel,则可以在此跳过CashDrawerViewModel

希望它有帮助!