Chcę pobrać z bazy kilku pierwszych użytkowników, których nick zawiera danego stringa:
var users = await dbContext.Users
.Where(u => u.UserName.Contains(query.UserName))
.Take(query.Limit)
.Select(u => userMapper.UserShortInfo(u))
.ToListAsync(cancellationToken);
UserShortInfoDto
jest potrzebne w kilku innych DTO, dlatego mam metodę mapującą:
public UserShortInfoDto UserShortInfo(User user) => new UserShortInfoDto
{
Id = user.Id,
UserName = user.UserName,
AvatarUrl = GetAvatarUrl(user.Id)
};
Do selekta przekazuję Func<User, UserShortInfoDto>
, a powinienem Expression<Func<User, UserShortInfoDto>>
. Tak więc napisałem osobną metodę zwracająca Expression
:
public Expression<Func<User, UserShortInfoDto>> UserShortInfoExpr() => u =>
new UserShortInfoDto
{
Id = u.Id,
UserName = u.UserName,
AvatarUrl = GetAvatarUrl(u.Id)
};
Tylko że to oznacza duplikację kodu - te dwie metody robią prawie to samo (i podobna duplikacja wystąpi nie raz). Nie mogę zwrócić stąd u => UserShortInfo(u)
, bo kompilator zrozumie, że do mapowania potrzebny jest cały User
, i EF pobierze wszystkie kolumny. Jak sobie z tym poradzić?
EDIT: W AutoMapperze jest chyba coś takiego jak ProjectTo
, ale sądząc po wpisach na tym forum i artykułach takich jak ten nie jest on już modny w świecie .NETu. ;(