Нулевой внешний ключ в базе данных - но почему? - PullRequest
1 голос
/ 09 ноября 2019

У меня есть база данных, полная автомобилей. Каждое транспортное средство может иметь много фотографий. Очевидно, что таблица изображений имеет внешний ключ транспортного средства.

Когда я добавляю изображение, а затем пытаюсь получить его, я не могу. Это связано с тем, что внешний ключ транспортного средства возвращается как нулевой. Проблема в том, что я не понимаю почему. В этот момент следует понимать, что на уровне базы данных все поля в таблице изображений заполняются, как и ожидалось. Есть 3 поля Id (PK, int), Picture (nVarChar(max)) и VehicleId(FK, int)). Важно отметить, что внешний ключ (VehicleId) заполнен действительным идентификатором транспортного средства.

Я использую MVC.

Прежде всего, код для модели изображения.

public class Picture
{
    public int Id {get; set;}
    public string Image {get; set;}
    [ForeignKey("VehicleId")]
    public virtual Vehicle Vehicle{get;set;}
}

Во-вторых, код Picture Controller, который сохраняет изображение. Обратите внимание, как я устанавливаю внешний ключ автомобиля.

ВАЖНО Подсказка - Если я вставлю тестовый код непосредственно перед возвратом созданного, чтобы получить изображение, я смогу. Внешний ключ автомобиля, кажется, установлен. Если я просто запускаю приложение и сразу пытаюсь получить изображение (т. Е. Без добавления нового), внешний ключ автомобиля становится пустым. Но почему? Я включил вызываемый код, который извлекает отдельное изображение.

public async Task<IActionResult> PostNewPicture(int vehicleId_, PictureViewModel picture_)
{
    try
    {
        if(ModelState.IsValid)
        {
            var vehicle = _vehicleRepository.GetVehicleById(vehicleId_);
            if (vehicle == null) return BadRequest("Vehicle Not Found");

            var newPicture = _mapper.Map<Picture>(picture_);
            newPicture.Vehicle = vehicle;
            _vehicleRepository.AddPicture(newPicture);
            if (await _vehicleRepository.SaveChangesAsync())
            {
                var url = _linkGenerator.GetPathByAction("GetIndividualPicture", 
                                                        "Pictures",
                                                        new {vehicleId_ = newPicture.VehicleForeignKey.Id,
                                                             pictureId_ = newPicture.Id});
                var pictureViewModel = _mapper.Map<PictureViewModel>(newPicture);
                return Created(url, _mapper.Map<PictureViewModel>(newPicture)); 
            }
        }
        return BadRequest("Failed to save the picture");
    }
    catch(Exception ex)
    {
        return BadRequest($"Exception Thrown :  {ex}");
    }
}

Код для извлечения отдельного изображения:

public Picture GetIndividualPicture(int vehicleId_, int pictureId_)
    {
        _vehicleContext.Pictures.Include(vp => vp.Vehicle);
        IEnumerable<Picture> pictures =  from v in _vehicleContext.Pictures.ToList()
                    .Where(x => x.Vehicle.Id == vehicleId_
                            && x.Id == pictureId_) select v;    
        return pictures.FirstOrDefault();
    }

Почему VehicleForeignKey имеет значение Null, когда оно четко установлено наточка добавления?

1 Ответ

0 голосов
/ 13 ноября 2019

Слава Герту Арнольду за это. Он правильно заявляет второй фрагмент кода. У вас нет _vehicleContext.VehiclePictures.Include (vp => vp.VehicleForeignKey)

Я чувствую себя немного обманщиком, отвечая на это сам - опять же, это был Герт. Вот мой чек в примечаниях к этому ....

12 ноября 2019 года. Контроллер картинок - я не мог понять, почему внешний ключ с таблицей картинок всегда возвращался как ноль. Ответ был, потому что я не включал его. См. Включить в запрос ниже. Не включайте это, и Автомобиль всегда нулевой. ТАКЖЕ - я использовал .ToList () сразу после того, как .Include (vp => vp.Vehicle) этого не делает - он загружает весь набор результатов в память ДО ПЕРЕД любой фильтрацией

    public Picture GetIndividualPicture(int vehicleId_, int pictureId_)
        {
            IEnumerable<Picture> pictures =  from v in _vehicleContext.Pictures
                        .Include(vp => vp.Vehicle)
                        .Where(x => x.Vehicle.Id == vehicleId_
                                && x.Id == pictureId_) select v;    
            return pictures.FirstOrDefault();
        }
...