Best way to control unicity of an attribute using EF Code First

霸气de小男生 提交于 2021-01-29 03:32:12

问题


I've got a class User which has an attribute Name that must be unique. So far I've investigated 3 ways of checking this:

  • Annotations

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

Problem is, by trying to insert a user with a repeated name it throws this ex: as you can see, I would have to navigate into the inner exceptions (which I don´t know if it is possible, but I assume it is) and the last inner exception´s message is not user friendly at all.

  • Fluent Api

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

I haven´t tried it but I believe it is has the same problem that Annotations.

  • Check by hand

controller code:

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

Problem: the check depends on my code, which may not be as accurate as date base checkings. Besides I will need to program more logic than the other two options. And last but no least if somehow I access the database directly there will be no checks at all.

I need to know which is the best practice to do this, because I'm trying to learn on my own, and I would like to do things as best as possible.


回答1:


You should actually do both, a check in code and a uniqueness index as a final guard when concurrent users manage to insert identical records after all. (Because of the latency between the check and the actual insert).

This means that you always have to catch exceptions when you call SaveChanges, but that's not a bad idea anyway.

For the uniqueness check you could use the mechanism I described here, just change email into Name and you're good to go.

You could dig up the last exception message from a chain of inner exceptions by this extension method:

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


来源:https://stackoverflow.com/questions/41536964/best-way-to-control-unicity-of-an-attribute-using-ef-code-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!