ViewModel与另一个ViewModel的集合 - AutoMapper可以帮助我吗?

时间:2011-03-28 03:09:38

标签: c# linq asp.net-mvc-3 viewmodel automapper

我有一个看起来像这样的ViewModel:

public class CreateReviewViewModel
{
   public string Title { get; set; }
   public decimal Score { get; set; }
   public ICollection<RecommendationViewModel> Recommendations { get; set; }
}

所以,前两个是基本的原生类型 - 容易。

第三个属性是另一个ViewModel的集合:

public class RecommendationViewModel
{
   public RecommendationType RecommendationType { get; set; }
   public bool IsRecommendedFor { get; set; }
}

RecommendationType是我的域模型中的enum,其中byte个值代表不同的“推荐”。

在我的[HttpGet]行动中,我这样做:

var model = new CreateReviewViewModel
{
   Recommendations = SomeMethodWhichLoopsThroughTheEnumMembersAndCreatesTheModel();
}
return View(model);

所以我最终得到RecommendationViewModel的列表,bool属性设置为false

然后在我的视图中,我使用 EditorTemplates:

@Html.EditorFor(model => model.Recommendations)

调用自定义编辑器模板,该模板为两个属性呈现标签和复选框。凉。

所以 - 有背景,希望有意义。

如何在Review操作中将ViewModel映射到[HttpPost]域模型?

Review对象的部分如下所示:

public class Review
{
   public bool IsRecommendedForA { get; set; }
   public bool IsRecommendedForB { get; set; }
   // etc
}

我目前正在进行这样的自定义映射:

var review = new Review();
review.IsRecommendedForA = this.Recommendations.SingleOrDefault(x => x.RecommendationType == RecommendationType.A).IsRecommendedFor;
review.IsRecommendedForB = this.Recommendations.SingleOrDefault(x => x.RecommendationType == RecommendationType.B).IsRecommendedFor;

这非常乏味。

我可以使用AutoMapper执行上述操作吗?

当然,我可以只是将所有不同的RecommendationType作为基本属性添加到ViewModel而不是集合,但是我的View变得复杂,我无法使用EditorTemplates隐式循环集合 - 我必须为每个属性写出Html.EditorFor

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

我有一个可能的解决方案

Mapper.CreateMap<CreateReviewViewModel, Review>()
   .ForMember(dest => dest.IsRecommendedForA, opt => opt.MapFrom(src => src.IsRecommendedFor(RecommendationType.A)))
   .ForMember(dest => dest.IsRecommendedForB, opt => opt.MapFrom(src => src.IsRecommendedFor(RecommendationType.B)));

其中IsRecommendedFor是一个钩子属性,使用我问题前面所述的LINQ表达式来确定模型是否包含属性,然后检查它。

这比手动从左到右更好,但仍然不是很好。

我已经看了一下自定义转换器/解析器,但是没有人接受额外的参数(例如,使用此参数解析此问题),所以我看不出如何使用它们。

我现在会继续这样做,但希望有人知道如何做得更好。

答案 1 :(得分:0)

您是否需要为每个可能的枚举值单独存储这些布尔值?标志意味着你可以启用多种类型......我觉得这会更好:

public class Review {
    public RecommendationType Types { get; set; }

    public bool IsReviewFor(RecommendationType types) {
        // bitwise comparison, check if the flags 
        // given are in the Types property also
    }
}

在添加/删除新类型时,更容易映射,更少代码,更具可扩展性。

myReview.IsReviewFor(RecommendationType.X | RecommendationType.Y | RecommendationType.Z)