Вот как это делает мой DAL:
List<entity> customers = SQL.Read(new SearchCriteria(), new Customers());
Для выполнения объединений:
List<entity> customers = SQL.Read(new SearchCriteria(), new Customers(new Orders(new OrderDetails())));
Класс DTO сам определяет, к какой таблице обращаться, а его свойства определяют, какие столбцы получить.
Я не могу ответить, является ли это лучшей или хорошей практикой. Это практика, которая работает для меня в течение длительного времени. Нет никаких посторонних методов, таких как «GetById», «GetAll» и т. Д.