2017-01-08 6 views
1

У меня есть класс User, у которого есть атрибут Name, которое должно быть уникальным. До сих пор я исследованный 3 способа проверить это:Лучший способ управления уникальностью атрибута с использованием кода EF Сначала

  • Аннотация

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

Проблема, пытаясь вставить пользователь с повторяющимся именем он бросает этот пример: DbUpdateException , как вы можете видеть, мне нужно было бы перейти во внутренние исключения (которые я не знаю, если это возможно, но я предполагаю, что это так), и последнее сообщение внутреннего исключения не совсем удобно.

  • Свободный Api

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

Я haven't попробовал это, но я считаю, что это та же самая проблема, что аннотаций.

  • Проверить вручную

код контроллера:

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

Проблема: проверка зависит от моего кода, который не может быть столь же точны, как дата базовых поверок. Кроме того, мне нужно будет запрограммировать больше логики, чем два других варианта. И последнее, но не менее важно, если каким-то образом я получаю доступ к базе данных напрямую, никаких проверок вообще не будет.

Мне нужно знать, какая из лучших практик для этого, потому что я пытаюсь учиться самостоятельно, и я хотел бы делать все как можно лучше.

ответ

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