Я занимаюсь разработкой проекта, в котором хранилище базы данных закодировано так:
public List<UserDTO> ShowAll()
{
return OnConnect<List<UserDTO>>(db =>
{
IEnumerable<User> users = db.Users;
return users.
ToListUserDTO();
});
}
public List<AnotherUserDTO> ShowAll()
{
return OnConnect<List<AnotherUserDTO>>(db =>
{
IEnumerable<User> users = db.Users;
return users.
ToAnotherUserDTO();
});
}
public TReturn OnConnect<TReturn>(Func<BankManagerDockAuthorizationEntitiesWrapper, TReturn> action)
{
TReturn result = default(TReturn);
OnConnect(db =>
{
result = action(db);
});
return result;
}
Теперь, если я хочу получить только идентификатор пользователя из базы данных, я должен создать другой метод, который будет запускать ToUsersWithJustIdDTO()
. Из четверки я могу сделать что-то вроде этого:
var users = repo.ShowAll()
.Select(x => new UserViewModel
{
Id = x.Id
})
.ToList();
, но ShowAll()
запустит огромный SQL-запрос и получит все о пользователе. Это не хорошо.
Лучшим решением для меня было бы создание универсального метода ShowAll
, который T
типа и users
будет автоматически отображаться на этот тип T
, что-то вроде этого:
IEnumerable<UserViewModel> users1 = repo.ShowAll<UserViewModel>();
IEnumerable<AnotherUserViewModel> users1 = repo.ShowAll<AnotherUserViewModel>();
Но я действительно не знаю, как это сделать. Мне удалось получить IQueryable
из хранилища и затем выбрать, например:
public IQueryable<User> GetUsers()
{
return OnConnect<IQueryable<User>>(db =>
{
return db.Users;
});
}
и использование:
var users = repo.GetUsers() // its IQueryable, so query is not launched yet
.Select(x => new UserViewModel
{
Id = x.Id,
})
.ToList();
Теперь он должен работать только SELECT Id from Users
.. но это не работает. Я не могу сделать это: контекст закрывается после GetUsers
, и я не могу сделать Select
. Что еще я могу сделать?