ASP.net MVC EF Codefirst重复条目

时间:2013-10-04 16:06:59

标签: c# asp.net entity-framework ef-code-first duplicates

使用Asp.net MVC 4和EF 5.0

问题:

每当我在下拉列表中选择一个用户并将帖子提交给Action时。 发生了两件事:

  1. 用户被添加到DinnerEvent中,应该是:

  2. 选中的用户是重复的,因此我现在在数据库的User表中有两个用户实例。这很糟糕。 :(




  3. 以下是设置

    我创建了两个实体:  晚餐活动和用户

    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; }
    }
    

1 个答案:

答案 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();
    }
}