Проблема при получении дочерней таблицы ASPNET Core API - PullRequest
0 голосов
/ 20 сентября 2018

Я создал API с ASPNET Core 2, у которого есть служба BlogPost.Сервис занимается созданием постов и тегов в блоге.«Теги» связаны с BlogPosts (как их дети, с помощью blogpostid), но я не могу найти способ отобразить эти теги при получении блогов.

Это то, что я получаюна данный момент.

{
    "id": 3,
    "title": "Im Just Testing",
    "body": "Esta Bien senor",
    "type": "News",
    "dateCreated": "9/20/2018 12:00:00 AM",
    "author": "Dante",
    "tags": []
}

Это мой контроллер ->

[HttpGet("posts/{id}")]
public IActionResult GetBlogPostById(int id, bool includePostTags = true)
{
    var blogPost = _blogPostService.GetBlogPostById(id, includePostTags);

    if(blogPost == null)
    {
        return NotFound();
    }

    var blogPostDto = _mapper.Map<BlogPostDto>(blogPost);
    return Ok(blogPostDto);
}

Это мой BlogPostDTO

public class BlogPostDto
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
    public string Type { get; set; }
    public string DateCreated { get; set; }
    public string Author { get; set; }

    public ICollection<BlogPostTagDto> Tags { get; set; }
        = new List<BlogPostTagDto>();
}

И, наконец, это мой объект BlogPostTag ->

public class BlogPostTag
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    [MaxLength(50)]
    public string TagName { get; set; }

    [MaxLength(200)]
    public string Description { get; set; }

    [ForeignKey("BlogPostId")]
    public BlogPost BlogPost { get; set; }
    public int BlogPostId { get; set; }
}

И мой BlogPostTagDto

public class BlogPostTagDto
{
    public int Id { get; set; }
    [Required(ErrorMessage = "You should provide a Tag Name value.")]
    [MaxLength(50)]
    public string TagName { get; set; }

    [MaxLength(200)]
    public string Description { get; set; }
}

TLDR : BlogPostTags созданы (я проверил базу данных), но я не могу получить их в "«Получить все сообщения».

BlogPostService ->

public BlogPost GetBlogPostById(int id, bool includePostTags)
{
    if(includePostTags)
    {
        return _context.BlogPosts.Include(c => c.BlogPostTags).Where(c => c.Id == id).FirstOrDefault();
    }
    return _context.BlogPosts.Where(c => c.Id == id).FirstOrDefault();
}

и DataContext (возможно, это помогает) ->

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        Database.Migrate();
    }

    public DbSet<User> Users { get; set; }
    public DbSet<BlogPost> BlogPosts { get; set; }
    public DbSet<BlogPostTag> BlogPostTags { get; set; }
}

BloGPost ENTITY

public class BlogPost
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    [MaxLength(100)]
    public string Title { get; set; }

    [Required]
    [MaxLength(500)]
    public string Body { get; set; }
    public string Type { get; set; }
    public string DateCreated { get; set; }
    public string Author { get; set; }

    public ICollection<BlogPostTag> BlogPostTags { get; set; }
        = new List<BlogPostTag>();
}

Добавлен профиль Mapper ->

    public AutoMapperProfile()
    {
        CreateMap<User, UserDto>();
        CreateMap<UserDto, User>();
        CreateMap<BlogPost, BlogPostDto>();
        CreateMap<BlogPostDto, BlogPost>();
        CreateMap<BlogPostTag, BlogPostTagForCreationDto>();
        CreateMap<BlogPostTagForCreationDto, BlogPostTag>();
       // CreateMap<BlogPostTagForCreationDto, BlogPostTag>();
    }

решено:

Видимо, в моем BlogPostDto мне пришлось получить "BlogPostTagForCreationDto" вместо обычного Dto.

    public ICollection<BlogPostTagForCreationDto> BlogPostTags { get; set; }
        = new List<BlogPostTagForCreationDto>();

Этот ПЛЮС, изменяющий имя с «Теги» на «BlogPostTags», похоже, решил мою проблему.Мне нужно больше узнать, почему это произошло.

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Мне кажется, что вам не хватает отображения:

CreateMap<BlogPostTag, BlogPostTagDto>();
0 голосов
/ 20 сентября 2018

После подтверждения в комментариях, что проблема заключается в разнице между именами BlogPostTags и Tags, становится очевидным, что AutoMapper необходимо указать для сопоставления от BlogPostTags до Tags при отображении из BlogPost до BlogPostDto.Это можно настроить внутри вашей AutoMapperProfile, например так:

public AutoMapperProfile()
{
    // ...

    CreateMap<BlogPost, BlogPostDto>()
        .ForMember(x => x.Tags, opt => opt.MapFrom(x => x.BlogPostTags));
}

Все, что мы здесь делаем, - это создание явной карты из BlogPost в BlogPostDto, котораяпозволяет нам контролировать определенные свойства по мере их отображения.В этом случае мы просто заявляем, что хотим от MapFrom BlogPostTags до Tags, соответственно.

0 голосов
/ 20 сентября 2018

Возврат BlogPostDto вместо BlogPost из вашего GetBlogPostById метода в BlogPostService следующим образом:

public BlogPostDto GetBlogPostById(int id, bool includePostTags)
{
    if(includePostTags)
    {
        return _context.BlogPosts.Where(c => c.Id == id).Select(bp =>
                new BlogPostDto
                {
                    Id = bp.Id,
                    Title = bp.Title,
                    .......
                    Tags = bp.BlogPostTags.Select(t => new BlogPostTagDto {
                             Id = t.Id,
                             ....
                           }).ToList()
                }).FirstOrDefault();
    }

    return _context.BlogPosts.Where(c => c.Id == id).Select(bp =>
                new BlogPostDto
                {
                    Id = bp.Id,
                    Title = bp.Title,
                    .......
                }).FirstOrDefault();
}

Затем в контроллере:

[HttpGet("posts/{id}")]
public IActionResult GetBlogPostById(int id, bool includePostTags = true)
{
    var blogPost = _blogPostService.GetBlogPostById(id, includePostTags);

    if(blogPost == null)
    {
        return NotFound();
    }

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