检索子表ASPNET Core API时出现问题

时间:2018-09-20 11:47:56

标签: c# asp.net-core entity-framework-core

我已经使用ASPNET Core 2创建了具有BlogPost服务的API。该服务处理创建博客文章和标签。 “标签”已链接到BlogPost(通过Blogpostid作为其子对象),但是在检索Blogpost时我找不到显示这些标签的方法。

这就是我现在要得到的。

bt-device -l | egrep '\(.*\)' | grep -oP '(?<=\()[^\)]+' | xargs -n1 bt-device -i 

这是我的控制器->

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

这是我的BlogPostDTO

[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);
}

最后这是我的BlogPostTag实体->

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>();
}

还有我的BlogPostTagDto

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; }
}

TLDR :创建了BlogPostTag(我检查了数据库),但是在“获取所有帖子”调用中无法检索它们。

BlogPostService->

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; }
}

还有DataContext(也许有帮助)->

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();
}

BloGPost实体

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; }
}

添加了Mapper个人资料->

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>();
}

已解决:

显然,在我的BlogPostDto中,我必须检索“ BlogPostTagForCreationDto”而不是普通的Dto。

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

此PLUS将名称从“标签”更改为“ BlogPostTags”似乎已经解决了我的问题。我必须进一步研究这种情况的发生原因。

3 个答案:

答案 0 :(得分:1)

在注释中确认问题出在名称BlogPostTagsTags之间存在差异之后,很明显,需要指示AutoMapper从BlogPostTags映射到{{1 }}从Tags映射到BlogPost时。可以在BlogPostDto内部进行配置,如下所示:

AutoMapperProfile

我们在这里所做的就是创建一个从public AutoMapperProfile() { // ... CreateMap<BlogPost, BlogPostDto>() .ForMember(x => x.Tags, opt => opt.MapFrom(x => x.BlogPostTags)); } BlogPost explicit 映射,这使我们能够在映射特定属性时控制它们。在这种情况下,我们只是简单地指出我们希望从BlogPostDto MapFromBlogPostTags

答案 1 :(得分:0)

通过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);
}

答案 2 :(得分:0)

在我看来,您缺少映射:

CreateMap<BlogPostTag, BlogPostTagDto>();