首先,我知道这个问题可能是Automapper entity framework foreign key is null的一个重复,但没有一个答案使它适用于我,我面临一些其他奇怪的问题,除此之外,我是.NET Core的新手, EF和Automapper :-)。
问题是,每当我使用Automapper创建或更新与Post
相关联的Category
时,该类别都会保存在数据库中,但它不应该返回,而我真的不明白为什么。它实际上返回null。 GetPost方法返回我期望的东西;这意味着FK已正确设置。
这是我得到的回应,请注意"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; }
}
我为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,所以如果有人在这里指导我,那将是非常感谢!
因此,正如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响应,只要我没有任何其他信息可以添加到我的响应中。在这种情况下,我可以跳过“加载链接实体”部分。这可能会成为一个问题,所以现在我明白问题是什么,但如果有什么可以解决的话,这不会“解决”问题。