如何从我的数据库中删除asp.net MVC中有两个主键的项目?

时间:2016-09-19 20:54:45

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 asp.net-mvc-5

大家好,我最近开始进入asp.net,我还是新手。我一直致力于一个项目并且已经碰壁了。让我先给你一些关于我项目的细节。我正在尝试创建一个具有少量功能的调度系统,其中一个功能可以添加已注册为“联系人”的其他现有用户,您可以使用这些用户共享任务。

用户通过搜索现有用户的电子邮件来执行此操作,如果存在,则可以将该用户添加为联系人。

现在这是我的问题。添加一个联系人,一切正常,但我没有删除它们。在删除操作链接的索引视图中,我尝试使用ContactUserId和ApplicationUserId只是为了意识到这不会起作用,因为它是一个关联类并且有两个主键。我非常不愿意帮助我的朋友建议我应该绑定两个主键,但我不知道如何解决这个问题。拜托,谢谢你的帮助。

控制器:

[Authorize]
public class ContactsController : Controller
{
    private ApplicationDbContext db = new ApplicationDbContext();

    // GET: Contacts
    public ActionResult Index()
    {

        IEnumerable<ApplicationUser> users = db.Users.ToList();

        IEnumerable<Contact> contacts = db.Contacts.ToList().Where(c =>     c.ApplicationUserID.Equals(User.Identity.Name));

        List<ApplicationUser> curUsers = new List<ApplicationUser>();

        foreach (var contact in contacts)
        {
            foreach (var user in users)
            {
                if (contact.ContactUserID.Equals(user.UserName))
                {
                    curUsers.Add(user);
                }
            }
        }

        ContactsViewModel cvm = new ContactsViewModel();
        cvm.users = curUsers;
        cvm.contacts = contacts;

        return View(cvm);
    }

    // GET: Contacts/Details/5
    public ActionResult Details(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Contact contact = db.Contacts.Find(id);
        if (contact == null)
        {
            return HttpNotFound();
        }
        return View(contact);
    }

    // GET: Contacts/Create
    public ActionResult Create()
    {
        return View();
    }

    // POST: Contacts/Create
    // To protect from overposting attacks, please enable the specific     properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include =     "ApplicationUserID,ContactUserID,Date")] Contact contact)
    {
        if (!String.IsNullOrWhiteSpace(contact.ContactUserID))
        {

            var count = db.Users.Count(u => u.UserName == contact.ContactUserID);

            if (count != 0)
            {
                contact.ApplicationUserID = User.Identity.Name;
                contact.Date = DateTime.Today; 
                db.Contacts.Add(contact);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            //User already exist error message                        
        }

        return View(contact);
    }

    // GET: Contacts/Edit/5
    public ActionResult Edit(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Contact contact = db.Contacts.Find(id);
        if (contact == null)
        {
            return HttpNotFound();
        }
        return View(contact);
    }

    // POST: Contacts/Edit/5
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "ApplicationUserID,ContactUserID,Date")] Contact contact)
    {
        if (ModelState.IsValid)
        {
            db.Entry(contact).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(contact);
    }

    // GET: Contacts/Delete/5
    public ActionResult Delete(string id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Contact contact = db.Contacts.Find(id);
        if (contact == null)
        {
            return HttpNotFound();
        }
        return View(contact);
    }

    // POST: Contacts/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(string id)
    {
        Contact contact = db.Contacts.Find(id);
        db.Contacts.Remove(contact);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
}

型号:

    public class Contact
{
    [Key]
    [Column(Order = 0)]
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string ApplicationUserID { get; set; }

    [Key]
    [Column(Order = 1)]
    [Display(Name = "Contact Email")]
    [Required (ErrorMessage = "Contact email is required")]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string ContactUserID { get; set; }

    public DateTime Date { get; set; }
}

索引视图:

@model MySchedule.ViewModels.ContactsViewModel

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Add", "Create")
</p>
<table class="table">
<tr>
    <th>
        <!--@@Html.DisplayNameFor(model => model.Date)-->
        First Name
    </th>
    <th>
        Last Name
    </th>
    <th>
        Email Name
    </th>
    <th></th>
</tr>
@{
var users = Model.users;
@foreach (var item in users)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.FirstName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.ActionLink("D", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("X", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}
}
</table>

视图模型:

 public class ContactsViewModel
{
    public IEnumerable<ApplicationUser> users { get; set; }
    public IEnumerable<Contact> contacts { get; set; }

}

1 个答案:

答案 0 :(得分:0)

简短回答是: 在EF中,如果在实体中定义复合键,则必须提供所定义的所有键(如果要使用“查找”以进行检索)。在您的情况下,您需要以这种方式调用Find:

Contact contact = db.Contacts.Find(applicationUserID, contactUserID);

如果您想要更多一点。请按照以下步骤实现您的目标:

重构您的GET删除操作,如下所示:

public ActionResult Delete(string applicationUserID, string contactUserID)
        {
            Contact contact = db.Contacts.Find(applicationUserID, contactUserID);
            if (contact == null)
                return HttpNotFound();

            return View(contact);
        }

重构您的帖子删除操作(DeleteConfirmed):

// POST: Contacts/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(string applicationUserID, string contactUserID)
        {
            Contact contact = db.Contacts.Find(applicationUserID, contactUserID);
            db.Contacts.Remove(contact);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

在您的Index.cshtml视图中,生成删除操作的链接:

@Html.ActionLink("X", "Delete", new { item.ApplicationUserID, item.ContactUserID })

这应该可以解决您的问题,但我认为您正在更改正在循环的属性。也许你应该迭代Model.contacts而不是Model.users

希望这有帮助!