AsQueryable() в слое бизнес-логики - плохая практика? (Я так думаю, но....)
Скажем, например, у меня есть (псевдокод):
public IEnumerable<User> GetUsers(string name)
в моем слое доступа к данным Entity Framework, который на данный момент делает .ToList()
перед возвратом, таким образом гарантируя, что уровень моей бизнес-логики не сможет помешать уровню доступа к данным.
Однако мне нужно немного отличаться от этого в моем слое бизнес-логики, например, мне нужно меньше данных (например, просто идентификаторы пользователя или дополнительная фильтрация).
Чтобы иметь эффективный слой БД, я бы хотел, чтобы другой метод возвращал подмножество данных (перегруженный метод или любой другой).
Тем не менее, я мог бы "обмануть" и опустить ToList(), и мой уровень бизнес-логики завершает работу AsQueryable(). Таким образом, мой уровень бизнес-логики способен манипулировать базовым SQL, который создается.
Что думают люди об AsQueryable () в слоях бизнес-логики? Мне кажется, что это утечка абстракции над моим уровнем доступа к данным, но это может быть невероятно удобно, и, возможно, потому что оно находится в пространстве имен LINQ (а не в пространстве имен EF), что это не так уж плохо в использовании?
РЕДАКТИРОВАТЬ
Что-то полезное, на которое следует обратить внимание (и аргумент против пропуска ToList()), заключается в том, что если вызывающий код ранее полагался на ToList () для привязки данных, т.е. чтобы избежать ошибки "Привязка данных напрямую к запросу хранилища (DbSet, DbQuery, DbSqlQuery) не поддерживается." Вы не получите ошибку времени компиляции, просто ошибка времени выполнения. Поэтому вам нужно убедиться, что ToList () определенно вызывается до уровня пользовательского интерфейса.
1 ответ
Лично я бы просто добавил второй метод, который выполняет ToList() в моем слое доступа к данным, и вызвал бы это. Так аккуратнее
functionA()
{
return myDB.entityA.AsQueryable();
}
functionB()
{
return functionA().ToList();
}
Возможно, вам понадобится вызвать эту же функцию откуда-то еще в будущем. Держите это в одном месте.