ViewModel с коллекцией другой ViewModel - Может ли AutoMapper помочь мне здесь? - PullRequest
2 голосов
/ 28 марта 2011

У меня есть ViewModel, которая выглядит следующим образом:

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

Итак, первые два являются базовыми нативными типами - easy.

Третье свойство - это коллекция другого 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)

, который вызывает пользовательский шаблон Editor, который отображает метку и флажок для двух свойств.Круто.

Итак - есть фон, который, надеюсь, имеет смысл.

Как мне сопоставить эту ViewModel с моделью Review домена в действии [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?

Конечно, я мог бы просто добавить все различные РекомендацииType в качестве базовых свойств в ViewModel вместо коллекции, но тогда мой View стал сложными я не могу использовать EditorTemplates для неявного цикла по коллекции - мне нужно было бы выписать Html.EditorFor для каждого свойства.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 29 марта 2011

Есть ли причина, по которой вам нужно хранить эти логические значения отдельно для каждого возможного значения перечисления? Флаг означает, что вы можете включить несколько типов ... Я чувствую, что это было бы лучше:

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)
0 голосов
/ 28 марта 2011

У меня есть одно возможное решение :

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, указанное ранее в моем вопросе, чтобы определить, содержит ли модель свойство и проверено ли оно.

Что лучше, чем руководство слева направо, но все же не очень хорошо.

Я посмотрел на пользовательские преобразователи / преобразователи, но ни один из них не принимает дополнительных параметров (например, разрешить из этого к этому, также используя этот параметр), поэтому я не вижу, как их можно использовать.

Сейчас я пойду с этим, но надеюсь, что кто-то знает, как это сделать лучше.

...