使用Asp.net MVC 4和EF 5.0
问题:
每当我在下拉列表中选择一个用户并将帖子提交给Action时。 发生了两件事:
用户被添加到DinnerEvent中,应该是:
选中的用户是重复的,因此我现在在数据库的User表中有两个用户实例。这很糟糕。 :(
以下是设置
我创建了两个实体: 晚餐活动和用户
DinnerEvent类具有指向一组服务员(用户)的导航属性
public virtual ICollection<User> Attendants { get; set; }
我为DinnerEvent和Users
创建了存储库DinnerEvent控制器
中的 AddAttendantToEvent操作[HttpPost]
public ActionResult AddAttendantToEvent(int users , int EventID )
{
if (ModelState.IsValid)
{
var user = userRepository.Find(users);
dinnereventRepository.Find(EventID).Attendants.Add(user); //Add the User to the Event.
dinnereventRepository.Save();
return RedirectToAction("Index");
}
else
{
return View();
}
}
视图 - 迭代所有事件,并添加一个填充了所有用户foreach事件的下拉列表。
@model Madklub.Models.ViewModel
@foreach (var item in Model.events) {
//Code to display available events
@using (Html.BeginForm("AddAttendantToEvent", "DinnerEvents")) {
@Html.Hidden("EventID", item.DinnerEventID);
@Html.DropDownListFor(m => m.users, new SelectList(Model.users, "UserID", "RoomNumber"));
<input type="submit" value="Add" />
}
ViewModel:
public class ViewModel
{
public IQueryable<DinnerEvent> events { get; set; }
public IQueryable<User> users { get; set; }
}
which is initialized like this:
Index Action in DinnerEventController:
public ViewResult Index()
{
ViewModel viewdata = new ViewModel();
viewdata.events = dinnereventRepository.AllIncluding(m => m.Attendants);
viewdata.users = userRepository.All;
return View(viewdata);
}
What am I doing wrong?
@model Madklub.Models.ViewModel
@foreach (var item in Model.events) {
//Code to display available events
@using (Html.BeginForm("AddAttendantToEvent", "DinnerEvents")) {
@Html.Hidden("EventID", item.DinnerEventID);
@Html.DropDownListFor(m => m.users, new SelectList(Model.users, "UserID", "RoomNumber"));
<input type="submit" value="Add" />
}
请求的存储库代码:
缩小为仅包含Save()方法。
请注意,这是Scaffolding的所有自动生成的代码。
public class ViewModel
{
public IQueryable<DinnerEvent> events { get; set; }
public IQueryable<User> users { get; set; }
}
答案 0 :(得分:2)
工作单元模式:(顺便说一下,让你的repo / uow IDisposable,以便你可以清理DbContext实例)
public class DinnerEventRepository : IDinnerEventRepository
{
MadklubContext _context = new MadklubContext();
public void Save()
{
_context.SaveChanges();
}
public DinnerEventRepository( MadklubContext context = null )
{
_context = context ?? new MadklubContext();
}
}
public class UserRepository //: IUserRepository
{
MadklubContext _context = new MadklubContext();
public void Save()
{
_context.SaveChanges();
}
public UserRepository( MadklubContext context = null )
{
_context = context ?? new MadklubContext();
}
}
public class RsvpUnitOfWork // come up with a better name
{
MadklubContext _context = new MadklubContext();
public DinnerEventRepository DinnerEventRepo { get; private set; }
public UserRepository UserRepo { get; private set; }
public RsvpUnitOfWork()
{
DinnerEventRepo = new DinnerEventRepository( _context );
UserRepo = new UserRepository( _context );
}
public void Save()
{
_context.SaveChanges();
}
}
用法:
[HttpPost]
public ActionResult AddAttendantToEvent(int users , int EventID )
{
if (ModelState.IsValid)
{
// this should be a using statement once you implement IDisposable
// e.g. using( var uow = new RsvpUnitOfWork() ) { ... }
var uow = new RsvpUnitOfWork();
// you need to validate that user != null
var user = uow.UserRepo.Find(users);
// possible null reference exception if dinner event not found for EventID
uow.DinnerEventRepo.Find(EventID).Attendants.Add(user); //Add the User to the Event.
uow.Save();
return RedirectToAction("Index");
}
else
{
return View();
}
}