Отображение идентификатора в модель для контроллера API - PullRequest
0 голосов
/ 10 января 2019

Я использую ядро ​​asp.net в проекте. (Я довольно новичок в этом)
У меня есть модель пользователя. код ниже является упрощенной версией:

public class User
{
    public int id { get; set; }
    // attribute declaration
    public ICollection<User> friends { get; set; }
}

Я использую службу Autopper для сопоставления моего API с этой моделью:

    public class UserResource
{
    public UserResource()
    {
        this.friendsId = new List<int>();

    }
    public int id { get; set; }
    // attribute declaration
    public ICollection<int> friendsId { get; set; }
}

рассмотрим запрос на публикацию в UserController со следующим телом:

{ 
 "id" : 1
"friendsId": [2,3,4],
}

Я хочу сопоставить целые числа в friendsId с идентификатором каждого пользователя в коллекции друзей. но я не могу понять, что делать. вот что у меня есть:

CreateMap<UserResource,User>()
            .ForMember(u => u.friends,opt => opt.MapFrom(????);

это правильный подход? если да, то как мне это реализовать?
или я должен изменить свою модель базы данных на это:

public class User
{
    public int id { get; set; }
    // attribute declaration
    public ICollection<int> friendsId { get; set; }
}

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Вам нужно будет реализовать пользовательский преобразователь значений. Они могут быть внедрены в, так что вы можете получить доступ к вещам, таким как ваш контекст внутри:

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));
0 голосов
/ 10 января 2019

Это поможет

CreateMap<UserResource,User>()
    .ForMember(u => u.friends,opt => opt.MapFrom(t => new User {FriendsId = t.friendsId);

public class User
{
    ...
    public ICollection<User> friends { get; set; }
}

Где друзья ICollection<User>, тогда как UserResource класс имеет ICollection<int>. Здесь есть несоответствие типов. Вам нужно сопоставить ICollection с ICollection, поэтому я произнесла new User ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...