То, что вы сделали, действительно является улучшением. Вы сделали серию Репозиторий классов, которые работают по жизни, чтобы вернуть вам сущности. Вы также можете поместить свои методы записи / обновления / удаления в новый объект Orders и разместить их в одном месте, что хорошо.
Ваша проблема, которую вы подняли в конце, - это проблема, с которой мы все имеем дело. Если вы когда-нибудь задумывались, почему LINQ-to-SQL или LINQ-to-Entities хороши, вот почему. Это связано с интерфейсом IQuerable. Используя любую из этих технологий, ваш метод Get
может возвратить IQuerable (Order) (по-видимому, возвращающий каждый возможный объект ордера), с которым вы можете затем выполнить LINQ; это фактически применило бы ваши бизнес-критерии к сгенерированному запросу SQL! Сначала это похоже на магию, но связано с природой IQuerable.
Если вы не используете такого провайдера LINQ 'db', тогда вы должны заработать свой профессиональный лейбл и сделать это по старинке: будьте умны. Вы все еще хотите использовать LINQ-to-object! Ах, да, вы делаете. Вы можете добавить GetByCustomer(CustomerID As Int)
, который принимает идентификатор клиента и возвращает IEnumerable (Order), и это будет возвращать 0 записей, или 10 или 50, в зависимости от записей. (Ваш объект Customer, вероятно, будет иметь свойство Orders, которое будет возвращать результаты этого метода.) Но вы не хотите продолжать добавлять собственные методы для каждой возможности. Допустим, вы часто хотите получить последний заказ Клиента; Вы, вероятно, хотите добавить GetLatestByCustomer(CustomerID as Int)
.
Но как насчет того, когда вам нужен только один раз клиент второй заказ . Было бы сумасшествием добавлять метод к вашему объекту DAL, GetSecondOrderByCustomer()
, верно? На данный момент мы действительно загромождаем наш объект DAL. В этом случае вы можете использовать LINQ против вашего метода GetByCustomer ():
Dim 2ndOrder As Order = (From O in DAL.Orders.GetByCustomer("123")
Order By OrderDate).Skip(1).Take(1)
Теперь, это довольно чисто, понятно, и вы не загромождаете свой DAL тем, что нам нужно было бы рассмотреть довольно специализированный запрос. Обратите внимание, что за кулисами вы получаете каждый заказ для данного клиента! Это не должно быть концом света; Я уверен, что ваша таблица заказов имеет индекс по CustomerID, верно? Но иногда вам нужно получить 60 записей заказов, чтобы получить второй.
Если в какой-то момент у вас возникнет действительно сумасшедшая потребность в запросе (получить все заказы между двумя датами, доставленные в Милуоки, оплаченные кредитной картой, пришедшие по факсу), вам, вероятно, придется предоставить прямую Опция -sql в вашем DAL. Вы хотите бороться, чтобы избежать этого, если можете, потому что тогда вы теряете свою абстракцию. Не могли бы вы добавить Orders.GetBetweenDates(FirstDate As date, SecondDate As date)
. Да уж . , , но видите опасность? Некоторые более поздние разработчики могут позвонить, чтобы получить все заказы на пару лет, а затем использовать LINQ для дальнейшей фильтрации. Это может легко вызвать сканирование таблицы за кулисами. Это те вещи, которые вы должны учитывать.
Вы должны быть осторожны. Когда вы хотите абстрагироваться (что хорошо!), Вы должны сделать компромиссы. Привлекательность LINQ-to-SQL заключается в том, что вы можете выполнить запрос LINQ, аналогичный приведенному выше примеру, и он просто получит одну запись из базы данных!