Вам нужно будет реализовать пользовательский преобразователь значений. Они могут быть внедрены в, так что вы можете получить доступ к вещам, таким как ваш контекст внутри:
public class FriendsResolver : IValueResolver<UserResource, User, ICollection<User>>
{
private readonly ApplicationDbContext _context;
public FriendsResolver(ApplicationDbContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public ICollection<User> Resolve(UserResource source, User destination, ICollection<User> destMember, ResolutionContext context)
{
var existingFriendIds = destMember.Select(x => x.Id);
var newFriendIds = source.friendsId.Except(existingFriendIds);
var removedFriendIds = existingFriendIds.Except(source.Friends);
destMember.RemoveAll(x => removedFriendIds.Contains(x.Id);
destMember.AddRange(_context.Users.Where(x => newFriendIds.Contains(x.Id).ToList());
return destMember;
}
}
Не уверен, будет ли это на самом деле работать, как я есть, так как я просто собрал все это здесь, но этого должно быть достаточно, чтобы начать работу. Основная идея заключается в том, что вы вводите все, что вам нужно, в решатель значений, а затем используете это для создания фактического материала, который вам нужно вернуть. В этом случае это означает запрос вашего контекста для User
сущностей с этими идентификаторами. Тогда в вашем CreateMap
:
.ForMember(dest => dest.friends, opts => opts.ResolveUsing<FriendsResolver>());
Это охватывает только одну сторону отношений, поэтому, если вам нужно отобразить другой путь, вам также может понадобиться специальный распознаватель для этого пути. Здесь я не думаю, что вы на самом деле. Вы должны иметь возможность просто обойтись:
.ForMember(dest => dest.friendsId, opts => opts.MapFrom(src => src.friends.Select(x => x.Id));