【发布时间】:2014-05-29 07:19:09
【问题描述】:
我遇到一个奇怪的问题,导航属性不在页面更新上,而是在创建上。 我正在使用 Entity Framework 6、ASP.NET MVC 5 的通用存储库模式。
这是框架代码:
我的背景:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base("DefaultConnection") { }
}
我的存储库实现:
public class EntityFrameworkRepository : IRepository, IDisposable
{
private ApplicationDbContext _context;
private readonly ConcurrentDictionary<Type, object> _dbSets =
new ConcurrentDictionary<Type, object>();
public EntityFrameworkRepository(ApplicationDbContext context)
{
_context = context;
}
public void Save<T>(T entity) where T : BaseModel
{
GetDbSet<T>().Add(entity);
_context.SaveChanges();
}
public void Update<T> (T entity) where T: BaseModel
{
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
}
}
这里Edit页面的Get基础使用AutoMapper在领域模型和视图模型之间进行映射。
public ActionResult Edit(int menuId, int? id)
{
MenuItem mi = _repository.Get<MenuItem>((int)id);
Mapper.CreateMap<MenuItem, MenuItemViewModel>();
MenuItemViewModel mivm = Mapper.Map<MenuItem, MenuItemViewModel>(mi);
///....///
}
这是行不通的方法。如您所见,完整对象 UseSiblingClaim 正在通过 id 检索并设置为 MenuItem itemToSave。我在调用 _repository.Update() 之前检查了对象,并且属性正确。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int menuId, [Bind(Include = "Id,Name,ControllerName,ActionName,Order,CustomUrl,Tooltip,IconClass,CanUseParentsClaim,DoesNotNeedClaim,UseSiblingClaim_Id")] MenuItemViewModel mivm)
{
if (ModelState.IsValid)
{
mivm.Menu = _repository.Get<Menu>(menuId);
if (mivm.UseSiblingClaim_Id != null)
{
mivm.UseSiblingClaim = _repository.Get<MenuItem>((int)mivm.UseSiblingClaim_Id);
}
MenuItem itemToSave = MapViewModelToModel(mivm, _repository);
_repository.Update<MenuItem>(itemToSave);
return RedirectToAction("Details", "Menu", new { Id = menuId });
}
return View(mivm);
}
这里是 MenuItem 类:
public class MenuItem : BaseModel
{
public MenuItem()
{
Children = new HashSet<MenuItem>();
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual MenuItem ParentMenuItem { get; set; }
public virtual Menu Menu { get; set; }
public string Name { get; set; }
///.....///
public virtual MenuItem UseSiblingClaim { get; set; }
}
映射方法在这里:UseSiblingClaim 正在设置中。
private static MenuItem MapViewModelToModel(MenuItemViewModel mivm, IRepository _repository)
{
MenuItem itemToSave = new MenuItem()
{
UseSiblingClaim = mivm.UseSiblingClaim,
Id = mivm.Id,
ActionName = mivm.ActionName,
CanUseParentsClaim = mivm.CanUseParentsClaim,
ControllerName = mivm.ControllerName,
CustomURL = mivm.CustomURL,
DoesNotNeedClaim = mivm.DoesNotNeedClaim,
IconClass = mivm.IconClass,
Menu = mivm.Menu,
Name = mivm.Name,
Order = mivm.Order,
ParentMenuItem = mivm.ParentMenuItem,
Tooltip = mivm.Tooltip,
};
return itemToSave;
}
这是视图模型:
public class MenuItemViewModel : BaseModel
{
public int Id { get; set; }
public int ParentMenuItem_Id { get; set; }
public MenuItem ParentMenuItem { get; set; }
public int Menu_Id { get; set; }
public Menu Menu { get; set; }
public IEnumerable<SelectListItem> SiblingItems { get; set; }
[DisplayName("Can Use Sibling's Claim")]
public int? UseSiblingClaim_Id { get; set; }
public MenuItem UseSiblingClaim { get; set; }
}
View 部分(这对于 Create() 和 Update() 是一样的:
<div class="form-group">
@Html.LabelFor(model => model.UseSiblingClaim_Id, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(x => x.UseSiblingClaim_Id, Model.SiblingItems, new { @class = "select2", @multiple = "multiple", @style = "width:100%" })
@Html.ValidationMessageFor(model => model.UseSiblingClaim_Id)
</div>
</div>
Model.SiblingItems 被创建并传递到视图中。
为什么不保留 UseSiblingClaim 导航属性?它适用于菜单项的创建,但不适用于更新?这与我使用通用存储库模式有关吗?请帮忙
【问题讨论】:
标签: c# asp.net asp.net-mvc-5 repository-pattern entity-framework-6