Где обрабатывать исключения БД в Entity Framework и шаблоне репозитория

как бы вы разработали этот сценарий (используя Entity Framework 4.1, Code First и шаблон репозитория): решение Visual Studio содержит следующие проекты

Solution
|-Web Application Project
|-DAL Project
|-Model Project

Итак, в Model Project есть различные классы. Предположим, у нас есть класс User со следующим определением (урезанным):

public class User{

    [Key]
    public int UserId { get; set; }

    ....

    //this property has a unique constraint created in a custom DB Initializer class
    public string email { get; set; }

    ....
}

В проекте DAL находятся методы репозитория (Insert, Update и т. д.), а также класс Initializer:

public class MyDatabaseInitializer : IDatabaseInitializer<MyDatabase>
{
    public void InitializeDatabase(MyDatabase context)
    {
        try
        {
            if (!context.Database.Exists())
            {
                context.Database.Create();
                context.Database.ExecuteSqlCommand(
                    "ALTER TABLE Users ADD CONSTRAINT uc_Email UNIQUE(Email)");
            }
        }
        catch (Exception ex)
        {
            throw ex.InnerException;
        }
    }
}

Метод Commit моего Класс Unit of Work выглядит следующим образом:

public string Commit()
{
    string errorMessage = string.Empty;

    try
    {
        Database.Commit();
    }
    catch (DbUpdateException updExc)
    {                                 
        errorMessage = updExc.InnerException.Message;            
    }                       

    return errorMessage;
}

Как вы видите, я обрабатываю DbUpdateExceptionв методе Commit()класса Unit of Work; это означает, что для каждого класса, который может вызвать ошибку обновления, это будет обрабатываться здесь.

Предположим, что кто-то вставляет записи пользователя со следующими данными:

(UserId,....,Email,...)
1, ... , person1@mail.com , ...
2, ... , person1@mail.com , ...

Очевидно, что это приведет к возникновению DbUpdateException. Конечно, это можно поймать и распространить туда, где оно должно появиться. У меня такое ощущение, что этот дизайн совершенно неверен:

  1. Валидация должна происходить для каждого свойства отдельно: разве это не должно быть верно и для уникальности значений поля? Означает ли это, что я должен объединить DAL и MODEL в один проект?

  2. Как мне обрабатывать ошибки, вызванные нарушением уникальности поля A в таблице A, поля B в таблице B, поля C в таблице C? Использование общего сообщения об ошибке «Значение уже существует» или «Нарушение уникальности» не очень описательно!

  3. Должен ли я вставить еще один уровень проекта-бизнеса, который позаботится об обработке таких ошибок?

  4. Должен ли я обрабатывать ошибки в действии/контроллере (ASP.NET MVC), выполняющем обновление?

  5. Как обработать правильное сообщение об ошибке в многоязычном приложении?

7
задан Benjamin Gale 12 August 2012 в 08:45
поделиться