使用实体框架,自动映射器为外键返回null

时间:2019-04-29 13:17:40

标签: entity-framework asp.net-core automapper

首先,我知道这个问题可能是Automapper entity framework foreign key is null的一个重复,但是没有一个答案对我有用,而且我还面临其他一些奇怪的问题,最重要的是,我.NET Core,EF和Automapper全新:-)。

问题是,每当我创建并使用自动映射器更新链接到Post的{​​{1}}时,该类别都会保存在数据库中,但是没有返回,而我真的不明白为什么。它实际上返回null。 GetPost方法返回我期望的结果;这意味着FK已正确设置。

这是我得到的回复,请注意Category

enter image description here

这是我的"Category": null,实体

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; } } 创建的Automapper配置:

Post

还有我的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); } 包含一个ID,标题,内容以及类别和用户DTO,在这里没有什么特别的。 PostDto只需将Post添加到DbContext(_postRepository.CreatePost(result);)的Posts列表中

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

我想有一种创建帖子并返回所有创建的字段(包括FK字段)的方法,因此,如果这里有人可以指导我完成任务,那就不胜感激了!

1 个答案:

答案 0 :(得分: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响应。在这种情况下,我可以跳过“加载链接的实体”部分。这个可能成为一个问题,所以现在我明白了问题所在,但是如果有任何要解决的问题,这不能“解决”问题。