Automapper возвращает ноль для внешних ключей с Entity Framework - PullRequest
1 голос
/ 29 апреля 2019

Прежде всего, я знаю, что этот вопрос может быть дубликатом Внешний ключ инфраструктуры сущностей Automapper имеет значение null , но ни один из ответов не помог мне сработать, и я столкнулся с некоторыми другими странными проблемами и Кроме того, я совершенно новичок в .NET Core, EF и Automapper: -).

Проблема в том, что всякий раз, когда я создаю или , обновляю Post, который связан с Category, с помощью Automapper, категория сохраняется в базе данных, но не возвращается, пока предполагается и я действительно не понимаю, почему. Это на самом деле возвращает ноль. Метод 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; }
}

Моя конфигурация 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);
    }

* * PostDto содержит Id, Title, Content, а также Category и User DTO, здесь ничего особенного. _postRepository.CreatePost(result); просто добавляет сообщение в список сообщений DbContext (_context.Posts.Add(post);)

CategoryId находится в полезной нагрузке, которую я отправляю, поэтому она уже должна быть включена. Но, похоже, она не работает. Я попытался жестко закодировать его (result.CategoryId = post.CategoryId;) без удачи. Поэтому я понял, что единственная разница с пользователем заключается в том, что я загружаю это .. Это не имеет смысла, но я просто загрузил категорию и заполнил ее в переменную (var category = _context.Categories.Where(c => c.Id == post.CategoryId).FirstOrDefault()), даже не применяя ее, и вдруг post.Category заполнен, не спрашивайте меня, почему. Во всяком случае, это не решение, я просто попробовал и не смог найти ответ.

Я полагаю, что есть способ создать сообщение и вернуть все созданные поля, включая FK, поэтому, если кто-нибудь здесь сможет мне помочь, это будет более чем признательно!

1 Ответ

0 голосов
/ 30 апреля 2019

Итак, как указал Хьюго, необходимо загрузить отношение, чтобы включить его в объект, который отправляет 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 при создании / обновлении, если у меня нет другой информации, которую можно добавить к моему ответу.В этом случае я мог бы пропустить часть «загрузка связанных сущностей».Это может стать проблемой, поэтому сейчас я понимаю, в чем проблема, но это не "решает" проблему, если есть что-то, что нужно решить.

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