【问题标题】:How do I delete an item from my database that has two primary keys in asp.net MVC?如何从我的数据库中删除在 asp.net MVC 中有两个主键的项目?
【发布时间】:2017-01-27 15:52:43
【问题描述】:

大家好,我最近开始接触 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; }

}

【问题讨论】:

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


    【解决方案1】:

    简短的回答是: 在 EF 中,如果您在实体中定义复合键,则必须提供您定义的所有键才能使用 Find 来检索它。在您的情况下,您需要以这种方式调用 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

    希望这会有所帮助!

    【讨论】:

    • 非常感谢,我现在明白了。但是问题是我必须迭代 Model.users 以显示联系人的电子邮件、名字和姓氏。
    • @DeanStrydom,没问题。乐意效劳。我认为您的 Contact 类没有这样的属性。也许您应该将所需的属性添加到您的联系人类中,然后在视图中显示这些属性。另外,当您询问多列删除的问题时,如果您认为它可以解决您的问题,请标记答案吗?
    猜你喜欢
    • 1970-01-01
    • 2016-03-10
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    相关资源
    最近更新 更多