映射器从数据库中获取数据是不是很糟糕
本文关键字:是不是 数据 获取 数据库 映射 | 更新日期: 2023-09-27 18:20:49
我想知道:映射器抽象有多复杂?
假设我有一个控制器的动作
ActionResult Find(QueryInputModel query)
模型看起来像这个
class QueryInputModel
{
public string Text {get;set;}
public IEnumerable<string> RegionCodes {get;set;}
}
除其他外,将输入模型转换为视图模型是操作的责任
class QueryViewModel
{
public string Text {get;set;}
public IEnumerable<Region> Regions {get;set;}
}
class Region
{
public string Name {get;set;}
public string Code {get;set;}
}
其中视图模型中的区域名称应该使用输入模型中的代码从数据库中获取。现在它是通过QueryMapper.Map(src)
方法完成的,看起来像这个
public QueryViewModel Map(QueryInputModel source)
{
var regions = regionRepository.Get(source.RegionCodes);
var result = new QueryViewModel {Text=source.Text, Regions=regions};
}
将这样的抽象称为Mapper正确吗?将直接映射和数据库查询混合在一个方法中可以吗?
好吧,这是我的看法。根据您所说的,您有一个用例"从区域代码中查找区域详细信息"。这个用例有两个输入端口和一个输出端口:
- 用户输入查询的方式是一个输入端口
- DB中从区域代码到区域详细信息的映射是另一个输入端口
- 将结果返回给用户的方法是一个输出端口
您在Map
函数中实现的所有逻辑都是您的用例逻辑。函数应该是这样的。
public void FindRegionDetailsFromRegionCodes(IUserQuery userQuery,
IRegionMapper regionMapper,
IUserDisplay userResult) {
var regions = regionMapper.Get(userQuery.RegionCodes);
userResult.ShowResult(regions);
}
带有:
interface IUserQuery {
IEnumerable<string> RegionCodes { get; }
}
interface IRegionMapper {
IEnumerable<Region> Get(IEnumerable<string> regionCodes);
}
interface IUserDisplay {
void ShowResult(IEnumerable<Region> regions);
}
这样,用例代码只关心操作执行的逻辑,而不关心如何完成每件事的细节。您可以通过TCP网络端口公开您的服务(通过适当地实现IUserQuery
和IUserDisplay
),或者通过抛出一对D20并在C:'
和繁殖仓鼠上查找随机文件(通过适当实现IRegionMapper
)来计算细节。
现在,事实是你在控制器操作中暴露了这个用例?好的因此,您的控制器操作可以通过传递它来调用FindRegionDetailsFromRegionCodes
:
- 您的
QueryInputModel
,实现IUserQuery
- 您的
QueryViewModel
,实现IUserDisplay
- 您的
RegionRepository
(我想它是类的名称),实现IRegionMapper
将Text
从输入复制到视图不是您的用例所关心的问题。这应该由你的行动来完成。(作为我论文的支持论据,如果你在某个时候复制了另一个字段,这不应该改变用例代码)
希望这能有所帮助。为了回答您的问题,真正的映射发生在DB中,这就是为什么我只称"DB"端口为IRegionMapper
。
ViewModel和DataModel之间的映射是手动映射,请尝试使用一些喜欢的映射第三方,如Automapper或Valueinjecter,两者都可以通过Nuget安装到您的项目文件中。个人更喜欢Valueinjecter,因为它更容易编码和理解。