2015-12-03 6 views
0

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

Итак, я создал репозиторий, чтобы оставить вещи, как db.Users.Where(u => u.Team == "MyTeam"), из моего домена.

После реализации шаблона репозитория общего типа, если мне нужен список пользователей в конкретной команде, я использую UserRepository.GetUsersByTeam("MyTeam").

Проблема моя UserRepository возвращается IEnumerable<EntityFrameworkUser>, вместо IEnumerable<DomainUser>, и для того, чтобы вернуть IEnumerable<DomainUser> Мне нужно отобразить DomainUser к EntityFrameworkUser где-то.

Итак, где конкретно вы сопоставляете класс EntityFrameworkUser с классом DomainUser?

Должно ли хранилище инкапсулировать логику отображения в дополнение к логике запроса?

Если мне нужна коллекция объектов пользователей домена, как выглядит стек вызовов для UserRepository.GetUsersByTeam("MyTeam")?

Поиск нашел только общие ответы, которые обычно цитируют Мартин Фаулер. Мне нужен конкретный пример.

+0

Может быть, это должно быть на http://programmers.stackexchange.com, потому что это доска-у? –

ответ

-1

Если цель данного метода состоит в том, чтобы просто всегда возвращать всех членов указанной команды, и вы никогда не будете применять дополнительные предложения к результату, вы можете изменить возвращаемый тип метода UserRepostory.GetUsersByTeam() от EF DbSet<User> до List<User>, затем смените оператор возврата на return db.Users.Where(u => u.Team == "MyTeam").ToList().

Вы больше не будете получать объекты EF из уровня хранилища.

+0

Это будет материализовать * весь список * каждый раз, аннулируя точку отложенного запроса результирующего перечисления. Поэтому, если кто-либо когда-либо называет 'GetUsersByTeam()' и добавляет к нему другое предложение, скажем, фильтруя его до одного пользователя, он все равно будет извлекать * каждого * пользователя из базы данных для этой команды. – David

+0

Мне кажется, что цель метода GetUsersByTeam - вернуть каждого пользователя в команде, и это то, что вы ожидаете от него. Конечно, это только один пример. –

1

Проблема моя UserRepository возвращается в рамочный объект пользователя DbSet

Это не должно быть тип возврата, потому что это будет ввести связь. Вы можете по-прежнему вернуть тип, но его следует полиморфно интерпретировать как другой тип.

Таким образом, хотя вы можете делать что-то подобное в вашем репозитории:

return db.Users; 

Тип возвращение не следует, что реализация типа (DbSet<User>?), Но что-то более общий характер:

public IQueryable<User> GetUsers() 
{ 
    return db.Users; 
} 

«Объекты EF» используются во всем домене, но домен не знает и не заботится об этом. Домен рассматривает его как запрашиваемую коллекцию моделей User.

+0

Я обновил вопрос для ясности. Я возвращаю IEnumerable , а не DbSet. – Legion

+0

@Legion: У вас есть два разных типа пользователя? Один для EF и один для домена? Похоже, что вы используете EF в корне неправильно в этом случае. EF должен сохранять ваши объекты домена. – David

+0

Да, у меня два. Один (для EF) предназначен для слоя сохранения и отображает от 1 до 1 в базу данных. Другая (для домена) содержит всю мою бизнес-логику и не является зеркалом таблицы пользователей базы данных. – Legion

1

Если вы хотите сохранить объект домена отдельно - сохраните его отдельно. Если репозиторий возвращает объекты из постоянного слоя, то он открывает дверь для проблем over-posting (особенно опасно, когда интерфейсные объекты используют одни и те же объекты). Я бы переместил логику отображения в другой класс и использовал его в ваших репозиториях.

Automapper - очень популярная библиотека для сопоставления другого объекта, например объекта домена с DTO и наоборот. Вы можете ввести Automapper в свои репозитории и использовать его для сопоставления IEnumerable<EntityFrameworkUser> по номеру IEnumerable<DomainUser>. Первое отображение регистра

Mapper.CreateMap<EntityFrameworkUser, DomainUser>(); 

Затем вызовите его из хранилища

return Mapper.Map<IEnumerable<EntityFrameworkUser>, IEnumerable<DomainUser>>(users); 
Смежные вопросы