我第一次尝试使用ViewModels使用AutoMapper。我有两个模特:
public class Item
{
public int ItemId { get; set; }
public bool Active { get; set; }
public string ItemCode { get; set; }
public string Name { get; set; }
public List<ItemOption> ItemOptions { get; set; }
//...
}
public class ItemOption
{
public int ItemOptionId { get; set; }
public string Name { get; set; }
public string Barcode { get; set; }
//...
}我把它变成了两个ViewModels:
public class ItemDetailViewModel
{
public int ItemDetailViewModelId { get; set; }
public int ItemId { get; set; }
public bool Active { get; set; }
public string ItemCode { get; set; }
public string Name { get; set; }
public List<ItemDetailItemOptionViewModel> ItemOptions { get; set; }
}
public class ItemDetailItemOptionViewModel
{
public int ItemDetailItemOptionViewModelId { get; set; }
public int ItemOptionId { get; set; }
public string Name { get; set; }
public string Barcode { get; set; }
}然后,在我的应用程序启动中设置以下内容:
Mapper.CreateMap<Item, ItemDetailViewModel>();
Mapper.CreateMap<ItemOption, ItemDetailItemOptionViewModel>();最后,我搭建了我的ItemDetailViewModel:

然后我构建了我的项目,并通过/ Item /Create添加了一个新项目
我在数据库中查看了一下,希望在Item表中有一个条目,但是我有ItemDetailViewModel和ItemDetailItemOptionViewModel表,这是我没想到的,数据是ItemDetailViewModel。
我想我把脚手架弄错了吧?我如何摆脱ViewModel而不让它成为主要业务模式的一部分?
进一步详细信息
如果无法使用ViewModel搭建控制器,那么如何在控制器中引用ViewModel并将更改保存回数据库?
例如,一旦我从db上下文中删除ItemDetailViewModel,下面的更改会是什么?
//
// POST: /Item/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ItemDetailViewModel itemdetailviewmodel)
{
if (ModelState.IsValid)
{
db.ItemDetailViewModels.Add(itemdetailviewmodel);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(itemdetailviewmodel);
}详细信息2
那么,我是否正确地认为我的索引/细节应该同样有效,或者是否有更好的方法来做到这一点?
//
// GET: /Item/
public ActionResult Index()
{
var items = db.Items.ToList();
var itemdetailviewmodel = AutoMapper.Mapper.Map<ItemDetailViewModel>(items);
return View(itemdetailviewmodel);
}
//
// GET: /Item/Details/5
public ActionResult Details(int id = 0)
{
ItemDetailViewModel itemdetailviewmodel = AutoMapper.Mapper.Map<ItemDetailViewModel>(db.Items.Find(id));
if (itemdetailviewmodel == null)
{
return HttpNotFound();
}
return View(itemdetailviewmodel);
}发布于 2013-12-29 19:14:34
脚手架没那么聪明。标准控制器脚手架模板正在创建带有控制器模型的DbContext,并假定您使用的是DB模型,而不是视图模型,而且它不使用Automapper。因此,您需要要么不使用脚手架,要么检查它在使用之前做了什么。
你使用脚手架的方式没有什么问题,它只是不应该做你想做的事。
更新--这是在没有脚手架的情况下如何做到的
// Without Automapper
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ItemDetailViewModel model)
{
if (ModelState.IsValid)
{
var item = new Item()
{
Active = model.Active,
ItemCode = model.ItemCode,
Name = model.Name,
ItemOptions = // code to convert from List<ItemDetailItemOptionViewModel> to List<ItemOption>
}
db.Items.Add(item);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
// with Automapper - not recommended by author of Automapper
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ItemDetailViewModel model)
{
if (ModelState.IsValid)
{
var item = Automapper.Mapper.Map<Item>(model);
db.Items.Add(item);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
} 您需要修改您的DbContext,使其具有IDbSet<Item> Items而不是IDbSet<ItemDetailViewModels> ItemDetailViewModels。
创建Automapper是为了从域模型映射到查看模型,而不是通过其他方式。我已经这样做了一段时间,但这是麻烦,并导致微妙的错误和其他维护问题。甚至吉米·博加德自己也是表示不应从视图模型映射到域模型。。
https://stackoverflow.com/questions/20828892
复制相似问题