使用EF Code First

时间:2017-01-08 19:36:00

标签: c# entity-framework code-first

我有一个类User,其属性Name必须是唯一的。 到目前为止,我已经调查了3种检查方法:

  • 注解

    [StringLength(100)]
    [Index(IsUnique = true)]
    public string Name { get; set; }
    

问题是,通过尝试插入具有重复名称的用户,它会抛出此ex: DbUpdateException 正如你所看到的,我将不得不导航到内部异常(我不知道它是否可能,但我认为是这样)并且最后一个内部异常消息根本不是用户友好的。

  • Fluent Api

https://stackoverflow.com/a/23155759/5750078

我没有尝试过,但我相信它与Annotations有同样的问题。

  • 手工检查

控制器代码:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Name,Password,Profile")] User user)
    {
        if (ModelState.IsValid)
        {
            lock (locker)
            {
                validateNameUnicity();
                db.Users.Add(user);
                db.SaveChanges();
            }
            return RedirectToAction("Index");
        }

        return View(user);
    }

问题:检查取决于我的代码,这可能不如日期基础检查准确。此外,我需要编程比其他两个选项更多的逻辑。最后但并非最不重要的是,如果不知何故我直接访问数据库,根本就没有检查。

我需要知道哪个是最好的做法,因为我想自己学习,我想尽可能做好事。

1 个答案:

答案 0 :(得分:4)

实际上,当并发用户设法插入相同的记录时,您应该同时执行这两项操作,检查代码唯一性索引作为最终防范。 (由于检查和实际插入之间的延迟)。

这意味着您在致电SaveChanges时始终必须捕获异常,但无论如何这都不是一个坏主意。

对于唯一性检查,您可以使用我所描述的here机制,只需将email更改为Name即可。

您可以通过此扩展方法从一系列内部异常中挖掘出最后一条异常消息:

public static string GetDeepestExceptionMessage(this Exception exception)
{
    string msg = string.Empty;
    while (exception != null)
    {
        msg = exception.Message;
        exception = exception.InnerException;
    }
    return msg;
}