Пользовательский репозиторий EF 4 - PullRequest
0 голосов
/ 18 ноября 2011

Это мой первый опыт работы с EF, поэтому я, вероятно, совершаю глупости. Любые комментарии по архитектуре приветствуются.

Итак, у меня есть типичный класс пользователей. У пользователей есть имя пользователя и список ролей:

 public class User
 {
     public string UserID{ get; set; }
     public List<Role> Roles { get; set; }
     public int Id { get; set; }
     public User()
     {
         Roles = new List<Role>();
     }
}

Мои доменные объекты живут в своей собственной библиотеке кода вместе с интерфейсами для своих репозиториев. Так что в этом случае будет IUserRepository со всеми методами CRUD плюс любые специализированные методы доступа к данным, которые мне могут понадобиться. Я пытаюсь реализовать эти интерфейсы репозитория с EF4 в другой библиотеке классов. Какие-либо проблемы с этим дизайном до сих пор?

Теперь в db (sql server) у меня есть типичные таблицы: Users, Roles и таблица «многие ко многим», отображающие пользователей на роли UsersRoles.

Я успешно настроил большинство методов CRUD в EF lib. Вот как выглядит Save

public void Save(Drc.Domain.Entities.Staff.User member)
    {
        using (var ctx = new DrcDataContext())
        {
            var efUser = MapFromDomainObject(member);
            if(member.Id < 1)
            {                    
                ctx.Users.AddObject(efUser);                    
            }
            else
            {                             
                ctx.Users.Attach(efUser);
                ctx.ObjectStateManager.ChangeObjectState(efUser, EntityState.Modified);
            }          
            ctx.SaveChanges();
            member.Id = efUser.UserId;                
        }            
    }

Теперь я не уверен, что это правильный способ сделать это, но это работает. Тем не менее, я сталкиваюсь с проблемами при выполнении удаления. Проблема с соответствующими таблицами

public void Delete(Drc.Domain.Entities.Staff.User member)
    {
        using (var ctx = new DrcDataContext())
        {
            var efUser = MapFromDomainObject(member);    ctx.Users.Attach(efUser);
            while (efUser.Roles.Count > 0)
            {
                ctx.ObjectStateManager.ChangeObjectState(efUser.Roles.First(), EntityState.Deleted);
            }                        
            ctx.SaveChanges();
            ctx.ObjectStateManager.ChangeObjectState(efUser, EntityState.Deleted);
            ctx.SaveChanges();
        }
    }

Если я не удаляю роли в цикле while, я получаю конфликт DELETE с ошибкой ограничения ссылки. Если я запускаю приведенный выше код, он удаляет правильные строки в таблице «многие ко многим», но также удаляет строки в таблице «Роли». Сейчас я нахожусь в тупике и собираюсь отказаться от идеи ORM и написать свои реализации репозитория в хорошем и надежном ADO.net.

- Edit Я предполагаю, что это неправильный способ реализации репозиториев с EF. Можно ли обойтись без засорения вашего домена кучей EF-ориентированных вещей?

1 Ответ

0 голосов
/ 18 ноября 2011

Используйте просто стандартный подход и не связывайтесь с состоянием объекта:

public void Delete(Drc.Domain.Entities.Staff.User member)
{
    using (var ctx = new DrcDataContext())
    {
        var efUser = MapFromDomainObject(member);
        ctx.Users.Attach(efUser);
        ctx.Users.DeleteObject(efUser);
        ctx.SaveChanges();
    }
}

Обычно в базе данных происходит каскадное удаление из таблицы User в таблицу соединения (если выне отключил это вручную).Таким образом, удаление пользователя также приведет к удалению соответствующих строк в соединительной таблице (но, конечно, не ролей).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...