我读过Vaughn(红皮书的作者)3部分有效聚合设计系列here
鉴于此代码:
public class Transaction
{
public Guid Id { get; private set; }
public int Number { get; private set; }
public DateTime Date { get; private set; }
public Guid ClientId { get; private set; } // other aggregate reference by ID only
public Guid BranchId { get; private set; } // other aggregate reference by ID only
public ICollection<TransactionItem> LineItems { get; private set; }
}
现在在用户界面中,如果我还要显示Branch.Name
和Client.FullName
&amp; Client.Company.Name
我应该创建平面ViewModel吗?
public class ViewModel
{
// other transaction properties
public string ClientName {get;set;}
public string ClientCompanyName {get;set;}
public string BranchName {get;set;}
}
或具有复杂类型的ViewModel?
public class ViewModel
{
// other transaction properties
public ClientDto { get; set; } // companyName and other details inside
public string BranchName {get;set;}
}
还是有更好的方法吗? 我想尽可能少写代码,但仍保持我的域模型清洁。
现在我正在编写原始sql(数据库视图)并将结果映射到ViewModel,有时我映射到数据库视图并创建映射,以便Entity Framework将结果具体化为viewmodel。
我还需要为我的视图返回的字段添加别名,以避免名称冲突。
但由于代码量不足,感觉不对。
使用数据库/原始sql是否可行?
AutoMapper可以帮我解决这个问题吗?
如果您可以分享您的操作方式,我也有兴趣查看您的代码。
答案 0 :(得分:2)
&#34;使用数据库/原始sql是否可行?&#34;
这将指的是今天许多人采用的称为CQRS的架构,其基于命令和查询是应由不同解决方案解决的不同问题的前提。单个统一模型通常必须双向拉伸,并且最终会比具有两个模型的可维护性,集中性和性能更差。
域模型针对处理命令进行了优化,因此尝试查询它是很痛苦的。您经常最终只需要调用许多存储库来构建一个中等复杂的视图模型。
但是,您经常会读到CQRS绑定到事件源并具有命令总线,通过投影更新的不同读取数据库并且必须异步处理命令。如果您正在构建高度并发的系统,那么您可能会受益于所有这些模式,但大多数系统永远不会需要它,并且使用这些技术会引入意外的复杂性。这是一篇关于CQRS Myths的有趣文章。
如果您使用的是RDBMS,那么我建议您只是绕过查询的域模型,但没有单独的读取数据库。
此外,关于您的平面与非平面视图模型问题,我会选择对消费者最实用的表示。但是,我赞成一个不平整的结构,因为它允许你创建有意义的整体(组高度凝聚力的数据)。通过将它们组合在一起,从现有视图模型构建更复杂的视图模型也可能更容易。