【发布时间】:2019-11-13 12:58:58
【问题描述】:
我有一个充满车辆的数据库。每辆车可以有许多图片。显然,pictures 表有一个 Vehicle 外键。
每当我添加图片,然后尝试检索它时,我都做不到。这是因为 Vehicle 外键返回为 Null。麻烦的是,我不明白为什么。此时,了解在数据库级别上,图片表中的所有字段都按预期填充。有 3 个字段 Id (PK, int)、Picture (nVarChar(max)) 和 VehicleId(FK, int))。至关重要的是,外键 (VehicleId) 填充了有效的车辆 ID。
我正在使用 MVC。
首先,图片模型的代码。
public class Picture
{
public int Id {get; set;}
public string Image {get; set;}
[ForeignKey("VehicleId")]
public virtual Vehicle Vehicle{get;set;}
}
其次,保存图片的图片控制器代码。注意我是如何设置车辆外键的。
重要提示 - 如果我在“返回已创建”之前立即将测试代码放入以检索图片,我可以。车辆外键似乎已设置。如果我只是运行应用程序并尝试立即检索图片(即不添加新图片),则 Vehicle Foreign key 为空。为什么呢?我已经包含了我调用的检索单个图片的代码。
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,当它在添加点明确设置时?
【问题讨论】:
-
因为你在后面的查询中没有
IncludeVehicleForeignKey属性。在PostNewPicture方法中,车辆被附加到上下文中。顺便说一句,不要从操作方法返回BadRequest。如果达到了这一点,请求本身就成功了。 -
抱歉 - 不完全确定您的意思。后面的查询是指“GetIndividualPicture”(第二个代码清单)中的查询吗?如果这样做,不包括 VehicleForeignKey 属性是什么意思?
-
是第二个代码sn-p。你没有
_vehicleContext.VehiclePictures.Include(vp => vp.VehicleForeignKey)。顺便说一句,你真的必须在那里删除ToList。它在过滤之前将整个表拉入内存。另外注意,不要使用VehicleForeignKey之类的名称,只需将其命名为Vehicle。 -
喜欢答案以外的建议。您不命名 VehicleForeignKey 而是命名 Vehicle 的原因是什么?至于 ToList 的删除 - 完全有道理 - 谢谢!!
-
通用命名约定。您指的不是“VehicleForeignKey”,而是车辆。在其他类中,Vehicle 可以是子实体。即使
_vehicleContext.VehiclePictures是 IMO 用词不当,我将其命名为_vehicleContext.Pictures。
标签: c# .net-core entity-framework-core