Automapper为Entity Framework的外键返回null

问题描述 投票:1回答:1

首先,我知道这个问题可能是Automapper entity framework foreign key is null的一个重复,但没有一个答案使它适用于我,我面临一些其他奇怪的问题,除此之外,我是.NET Core的新手, EF和Automapper :-)。

问题是,每当我使用Automapper创建或更新与Post相关联的Category时,该类别都会保存在数据库中,但它不应该返回,而我真的不明白为什么。它实际上返回null。 GetPost方法返回我期望的东西;这意味着FK已正确设置。

这是我得到的回应,请注意"Category": null,

enter image description here

这是我的Post实体

public class Post
{
    [Key]
    [StringLength(450)]
    public string Id { get; set; }

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

    [Required]
    [MaxLength(2500)]
    public string Content { get; set; }

    [ForeignKey("UserId")]
    public User User { get; set; }
    public string UserId { get; set; }

    [ForeignKey("CategoryId")]
    public Category Category { get; set; }
    public string CategoryId { get; set; }
}

我的Category实体:

public class Category
{
    [Key]
    [StringLength(450)]
    public string Id { get; set; }

    [Required]
    [MaxLength(150)]
    public string Name { get; set; }

    public int Weight { get; set; }
}

我为Post创建的Automapper配置:

AutoMapper.Mapper.Initialize(config =>
        {
            config.CreateMap<Category, CategoryDto>();
            config.CreateMap<Post, PostDto>();
            config.CreateMap<PostForCreationDto, Post>();
        });

而我的PostForCreationDto

public class PostForCreationDto
{
    [Required]
    [MaxLength(150)]
    public string Title { get; set; }

    [Required]
    [MinLength(25)]
    [MaxLength(2500)]
    public string Content { get; set; }

    [Required]
    public string CategoryId { get; set; }
}

以下是我尝试在PostController中创建帖子的方法:

public async Task<IActionResult> CreatePost([FromBody] PostForCreationDto post)
    {

        if (post == null)
        {
            return BadRequest();
        }

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var user = await _userManager.GetUserAsync(HttpContext.User);

        var result = Mapper.Map<Post>(post);
        result.UserId = user.Id;
        _postRepository.CreatePost(result);

        if (!await _postRepository.SaveAsync())
        {
            return BadRequest();
        }

        var createdPost = Mapper.Map<PostDto>(result);

        return Ok(createdPost);
    }

PostDto包含Id,Title,Content以及Category和User DTO,这里没什么特别的。 _postRepository.CreatePost(result);只是将帖子添加到DbContext的帖子列表中(_context.Posts.Add(post);

CategoryId在我发送的有效载荷中,因此它应该已被包含在内..但它似乎不起作用。我试图硬编码(result.CategoryId = post.CategoryId;)没有运气。因此我认为与用户的唯一区别是我加载它..这没有任何意义,但我只是加载了类别并将其存储在var(var category = _context.Categories.Where(c => c.Id == post.CategoryId).FirstOrDefault())中,甚至没有应用它,突然post.Category被填充,不要问我为什么。无论如何,这不是一个解决方案,我只是尝试了,但找不到答案。

我想有一种方法可以创建一个Post并返回所有创建的字段,包括FK,所以如果有人在这里指导我,那将是非常感谢!

entity-framework asp.net-core automapper
1个回答
0
投票

因此,正如Hugo指出的那样,需要加载关系以便包含在EF发送的对象中。这是我无法理解的事情..现在,我在我的帖子上下文中添加帖子后立即加载链接类别

_context.Posts.Add(post);
_context.Entry(post).Reference("Category").Load();

而我只是将它包含在我的GetPost方法中:

public Post GetPost(string postId)
    {
        return _context.Posts
                       .Include(p => p.User)
                       .Include(p => p.Category)
                       .FirstOrDefault(p => p.Id == postId);
    }

但我很确定这不是最好的做法,因为我正在点击数据库加载类别。这只是一个用于测试目的的练习,我相信一个好的做法是在创建/更新时返回NoContent响应,只要我没有任何其他信息可以添加到我的响应中。在这种情况下,我可以跳过“加载链接实体”部分。这可能会成为一个问题,所以现在我明白问题是什么,但如果有什么可以解决的话,这不会“解决”问题。

© www.soinside.com 2019 - 2024. All rights reserved.