映射器从db获取数据是不是很糟糕?

时间:2013-07-03 15:21:15

标签: c# asp.net-mvc mapping single-responsibility-principle

我想知道:映射器抽象有多复杂?

假设我有控制器的动作

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;}
}

其中视图模型中的区域名称应使用输入模型中的代码从db中获取。 现在它由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查询吗?

2 个答案:

答案 0 :(得分:1)

嗯,这是我的看法。根据您的说法,您有一个用例“从区域代码中查找区域详细信息”。该用例有两个输入端口和一个输出端口:

  • 用户输入查询的方式是一个输入端口。
  • 数据库中从区域代码到区域详细信息的映射是另一个输入端口。
  • 将结果返回给用户的方法是输出端口。

您在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网络端口公开您的服务(通过适当地实施IUserQueryIUserDisplay),或者通过抛出一对D20并在C:\上查找随机文件和繁殖仓鼠来计算详细信息(通过适当实施IRegionMapper)。

现在,事实是你在控制器动作中暴露了这个用例?好。因此,您的控制器操作可以通过传递它来调用FindRegionDetailsFromRegionCodes

  • 您的QueryInputModel,正在实施IUserQuery
  • 您的QueryViewModel,正在实施IUserDisplay
  • 您的RegionRepository(我认为这是该课程的名称),实施IRegionMapper

Text从输入复制到视图不是您的用例关注的问题。这应该通过你的行动来完成。 (作为我论文的支持论据,如果你在某个时候复制另一个字段,这不应该改变用例代码)

希望这会有所帮助。为了回答你的问题,真正的映射发生在DB中,这就是为什么我只调用“DB”端口IRegionMapper

答案 1 :(得分:-1)

您在ViewModel和DataModel之间的映射是手动映射,尝试使用一些帮助映射第三方,如Automapper或Valueinjecter,两者也可以由Nuget安装到您的项目文件中。个人更喜欢Valueinjecter,因为它更容易编码和理解。