2012-02-20 4 views
0

У меня есть ASP.NET MVC3 в C# и Razor. Архитектура приложения разделена на уровень доступа к данным (классы EF + репозиторий), уровень обслуживания, контроллер, ViewModels и вид.Как получить доступ к свойствам класса EF с уровня обслуживания

С моей службы слоя ProductServices я вызываю метод GetAllProducts подвергается мой Repository ProductRepository, который имеет следующую подпись:

IQueryable<Products> GetAllProducts() 

Таким образом, в пределах ProductServices я называю (productRepository является экземпляром ProductRepository):

var products = productRepository.GetAllProducts(); 

, который заполняет переменную products. Теперь я хотел бы получить доступ к названию продукта ProductName от productServices. Если я использую эту инструкцию:

var productNames = products.Select(m => m.ProductName).ToList(); 

Я создаю связь между ServiceLayer и EF (минуя хранилище). Это означает, что я должен добавить к ProductRepository методу с подписью:

IQueryable<string> GetAllProductsName() 

Однако, так как мне нужно другая информация о продукте в моем приложении, я должен создать один метод в productRepository для каждого поля Product класса? Правильно ли я рассуждаю? Благодаря

+0

Зачем вам нужен уровень сервиса, если он просто проксирует запросы? – Eranga

+0

спасибо за ваш ответ. Конечно, у меня также есть вся бизнес-логика и несколько методов на моем уровне обслуживания, вот почему мне это нужно – CiccioMiami

+0

Что заставляет вас думать, что этот тип связи плохой? – Eranga

ответ

1

Theres две школы мысли вокруг этого,

  1. Хранилище явно определяет способ взаимодействия с базой данных и должны жестко контролироваться. Поэтому методы в репозитории должны предоставлять перечисленные данные.
  2. Репозиторий разбивает сильную связь на конкретный тип источника данных, но не требует предоставления подробных и перечислимых наборов данных.

Лично я подписаться на второй, почему Heres:

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

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

Сказав, что предоставление неперечислимых источников данных откроет вам проблемы позже по дорожке, и даже если вы предоставите им очень важное значение для перечисления набора как можно скорее.

Если вы заинтересованы Heres мой взять на репозиториях: http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html, весь код также на GitHub

+0

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

+0

Я чувствую, что, обратившись к запрашиваемому напрямую, вы фактически не обходите репозиторий, вы предпочитаете продление времени выполнения. так что да, я был бы в порядке, используя select после того, как вы вернете набор из репозитория. Здесь также важно отметить, что выбор - это фактически функция LINQ, а не EF или вашего репозитория, и он довольно успешно работает и с перечислимым набором. –

+0

, и если я заранее знаю, что база данных (и, следовательно, EF) будет заменена? Если я получаю доступ к полям только из 'productRepository', я должен изменить только этот уровень – CiccioMiami

0

У вас есть вся информация в ваших productServices потому, что вы загрузить всю информацию из хранилища с помощью метода productRepository.GetAllProducts().Если вам нужна дополнительная информация от другого лица, вам необходимо расширить свои сервисы продукта с помощью новой службы.

Однако, так как мне нужен другая информация о продукте в моем приложении, должен создать один метод в productRepository для каждого поля класса продукта? Правильно ли я рассуждаю? Спасибо

В этой ситуации обычно я создаю метод Extensions для службы, а не в репозитории. У репозитория обычно есть программа CRUD и ничего больше.

+0

спасибо, это означает, что вы прямо обращаетесь к полям непосредственно на уровне обслуживания? Конечно, у меня есть другие методы, кроме GetAllProducts. Я не перечислял их здесь, потому что они не под вопросом. – CiccioMiami

+0

В этом случае да. Вы никогда этого не делаете, если вам нужна эта логика в другом приложении или контексте базы данных (e.q WPF App или Mobile App). С вашей архитектурой обслуживания вы можете справиться с этой ситуацией в хорошем смысле. – glenn