下载菜单中的自动映射IEnumerable

问题

我目前正在为我的MVC项目添加自动化,而且我被困住了。 现在我有一个User模型用于表示数据库中的数据。 我必须将该模型映射到EditUserModel,它将在调用Edit方法时使用。 EditUserModel有IEnumerable (对于下拉菜单),我似乎无法弄清楚如何映射。

试图解决方案

截至目前,我还没有尝试过任何事情。 我不确定IEnumerable的最佳位置在哪里或填充它的位置。 现在它正在控制器中填充。

User.cs

 public class User { [Key] public int UserID { get; set; } public string Username { get; set; } public string Password { get; set; } public int RoleID { get; set; } [ForeignKey("RoleID")] public virtual Role Role { get; set; } } 

EditUserModel.cs

 public class EditUserViewModel { [HiddenInput(DisplayValue = false)] public int UserID { get; set; } [Required] public String Username { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [DisplayName("Role")] [Required] public int RoleID { get; set; } //The trouble field public IEnumerable Roles { get; set; } } 

Controller.cs

 EditUserViewModel model = new EditUserViewModel(); //Population of the dropdown menu model.Roles = context.Roles .ToList() .Select(x => new SelectListItem { Text = x.Description, Value = x.RoleID.ToString() }); //Mapping that the automaper will take care of model.UserID = user.UserID; model.Username = user.Username; model.RoleID = user.RoleID; 

为了记录,这是我在对Jakub的回答的评论中所说的:

 public static class EnumerableExtensions { public static IEnumerable ToSelectList(this IEnumerable instance, Func text, Func value, Func selectedItem = null) { return instance.Select(t => new SelectListItem { Text = Convert.ToString(text(t)), Value = Convert.ToString(value(t)), Selected = selectedItem != null ? selectedItem(t) : false }); } } 

毋庸置疑,这是非常简单并且完成相同的事情(并且在属性路径不简单的情况下实际上更加健壮,因为Jakub的解决方案不适用于嵌套属性)。

(这不是一个真正的答案,我将其作为社区维基发布,仅仅是为了帮助阐述一点)

控制器是填充视图模型的理想场所。

您可以使用此扩展方法删除管道代码:

 public static class EnumerableExtensions { public static IEnumerable ToSelectList(this IEnumerable instance, Expression> text, Expression> value, Func selectedItem = null) { return instance.Select(t => new SelectListItem { Text = Convert.ToString(text.ToPropertyInfo().GetValue(t, null)), Value = Convert.ToString(value.ToPropertyInfo().GetValue(t, null)), Selected = selectedItem != null ? selectedItem(t) : false }); } public static PropertyInfo ToPropertyInfo(this LambdaExpression expression) { MemberExpression body = expression.Body as MemberExpression; if (body != null) { PropertyInfo member = body.Member as PropertyInfo; if (member != null) { return member; } } throw new ArgumentException("Expression is not a Property"); } } model.Roles = context.Roles.ToSelectList(r => r.RoleID, r => r.Description);