微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在ASP.NET实体框架中不允许重复

如何解决如何在ASP.NET实体框架中不允许重复

我是ASP.NET MVC和EF的新手,所以这可能是一个非常简单的问题,但是阻止用户尝试输入重复记录的最佳方法是什么?

我有一个名为Category的表,该表有两列IdCategoryNameId是PK,我在CategoryName上将索引值设置为唯一)。我想做的是防止用户输入相同的类别。

我的CategoriesController如下:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Library;

namespace Library.Controllers
{
    public class CategoriesController : Controller
    {
        private LibraryDbEntities1 db = new LibraryDbEntities1();

        // GET: Categories
        public ActionResult Index()
        {
            return View(db.Category.ToList());
        }

        // GET: Categories/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Category category = db.Category.Find(id);

            if (category == null)
            {
                return HttpNotFound();
            }

            return View(category);
        }

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

        // POST: Categories/Create
        // To protect from overposting attacks,enable the specific properties you want to bind to,for 
        // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,CategoryName")] Category category)
        {
            if (ModelState.IsValid)
            {
                db.Category.Add(category);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            int temp = Convert.ToInt32(cmd.ExcecuteScalar().To)

            return View(category);
        }

        // GET: Categories/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Category category = db.Category.Find(id);

            if (category == null)
            {
                return HttpNotFound();
            }

            return View(category);
        }

        // POST: Categories/Edit/5
        // To protect from overposting attacks,for 
        // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,CategoryName")] Category category)
        {
            if (ModelState.IsValid)
            {
                db.Entry(category).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(category);
        }

        // GET: Categories/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Category category = db.Category.Find(id);

            if (category == null)
            {
                return HttpNotFound();
            }

            return View(category);
        }

        // POST: Categories/Delete/5
        [HttpPost,ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Category category = db.Category.Find(id);
            db.Category.Remove(category);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

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

            base.dispose(disposing);
        }
    }
}

索引视图如下:

 @model Library.Category

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Category</h4>
        <hr />
        @Html.ValidationSummary(true,"",new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Id,htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Id,new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Id,new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.CategoryName,htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.CategoryName,new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.CategoryName,new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List","Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

我的问题是:如何防止用户两次输入同一类别?例如,我创建了一个名为“动作”的类别,我不希望任何其他用户都可以创建相同的类别。

解决方法

正如我在上面的评论中所说,您有两个选择。一种是向CategoryName字段添加唯一索引。这将强制数据库拒绝无效的更新。当然,这意味着您需要在代码中处理异常。

我更喜欢在代码中处理这种情况,尽可能避免出现异常。
对于创建操作,这涉及检查数据库中是否存在与提议的名称相同的CategoryName。

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,CategoryName")] Category category)
{
    ViewBag.ErrorMessage = "";
    if (ModelState.IsValid)
    {
        // Check if the cat name exists or not
        var cat = db.Category.FirstOrDefault(x => x.CategoryName == category.CategoryName);
        if(cat == null)
        {
            db.Category.Add(category);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        else
        {
            // Add here the logic required to inform your user about the problem
            ViewBag.ErrorMessage = "Duplicate Category Name";
            
        }
    }
    return View(category);
 }

但是您在“编辑”操作中有相同的问题。同样,在这里您还应防止用户将现有的CategoryName更改为另一个现有的CategoryName,但如果数据库中存在的与您正在编辑的相同,则不要这样做。

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,CategoryName")] Category category)
{
    ViewBag.ErrorMessage = "";
    if (ModelState.IsValid)
    {
        var cat = db.Category.FirstOrDefault(x => x.CategoryName == category.CategoryName  
                                             && x.Id != category.Id)
        if(cat == null)
        {
            db.Entry(category).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        else
        {
            // Inform your user about the problem
            ViewBag.ErrorMessage = "Duplicate category Name";
        }
    }
    return View(category);
}

最后,您可以在.cshtml中通知您的用户添加特定的DIV,并将错误消息存储在ViewBag中。当然,您可以添加一些样式/ css类(红色背景/颜色)来吸引用户对消息的关注。

@using (Html.BeginForm()) 
{
    if (!string.IsNullOrEmpty(ViewBag.ErrorMessage))
    {
        <div>
        <p>
            <h3>@Html.Raw(ViewBag.ErrorMessage)</h3>
        </p>
        </div>
    }
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。