E.F Core 和 Automapper 在通过 id 获取时没有获取所有数据
E.F Core and Automapper not getting all data when getting by id
我在 ASP.NET CORE api 中使用 EF Core 和 Auto Mapper,我有点难以理解为什么我在获取数据时没有获取所有数据身份证.
当我调试并查看数据时,它全部存在于变量中,但当它到达自动映射器部分时,就像某些数据被忽略了一样。
如何获取所有对应Id的数据
这是我的 GetAsset by Id 方法。
[HttpGet("{key:int}", Name = "getAsset")]
[EnableQuery]
public async Task<ActionResult<AssetDto>> GetAsset(int key)
{
var asset = await _context.Assets.Include(c => c.Category)
.Include(m => m.Manufacturer)
.Include(c => c.Condition)
.Include(l => l.Location)
.Include(f => f.AssetFiles)
.FirstOrDefaultAsync(i => i.Id == key);
if (asset == null) return NotFound();
var assetDto = _mapper.Map<AssetDto>(asset);
return assetDto;
}
这是我使用 automapper 的映射
CreateMap<Asset, AssetDto>().ReverseMap();
这是我的 AssetDTO
public class AssetDto
{ // Get and sets the Id property
public int Id { get; set; }
// Gets and sets the Name Property and sets it to required
[Required]
public string Name { get; set; }
// Gets and sets the CategoryId property
public int CategoryId { get; set; }
// Gets and sets the CategoryName property set it to NotMapped
[NotMapped]
public string CategoryName { get; set; }
// Gets and sets the ManufacturerId property
public int ManufacturerId { get; set; }
// Gets and sets the ManufacturerName property set it to NotMapped
[NotMapped]
public string ManufacturerName { get; set; }
//Gets and sets the Model property
public string Model { get; set; }
//Gets and sets the SerialNumber property
public string SerialNumber { get; set; }
// Gets and sets the PurchasePlace property
public string PurchasePlace { get; set; }
// Gets and sets the Quantity property
public int Quantity { get; set; }
// Gets and sets the AcquiredDate property
public DateTime AcquiredDate { get; set; }
// Gets and sets the PurchasePrice property/
public float PurchasePrice { get; set; }
// Gets and sets the CurrentValue property
public float CurrentValue { get; set; }
//Gets and sets the ConditionId property
public int ConditionId { get; set; }
// Gets and sets the ConditionName property set it to NotMapped/
[NotMapped]
public string ConditionName { get; set; }
// Gets and sets the LocationId property
public int LocationId { get; set; }
// Gets and sets the LocationName property set it to NotMapped
[NotMapped]
public string LocationName { get; set; }
// Gets and sets the RetiredDate property
public DateTime RetiredDate { get; set; }
// Gets and sets the Description property
public string Description { get; set; }
// Gets and sets the Files property set it to NotMapped
[NotMapped]
public ICollection<AssetFileDto> Files { get; set; } <-- updated
}
和我的资产模型
public class Asset
{ // Int property that gets/sets id
public int Id { get; set; }
// String property that gets/sets Name
[Required]
public string Name { get; set; }
//Foreign Key
//Int property that gets/sets category id
public int? CategoryId { get; set; }
// Foreign Key
// Int property that gets/sets Manufacturer id
public int? ManufacturerId { get; set; }
// String property that gets/sets model
public string Model { get; set; }
// String property that gets/sets serial number
public string SerialNumber { get; set; }
// String property that gets/sets purchase place
public string PurchasePlace { get; set; }
//Int property that gets/sets quantity
public int? Quantity { get; set; }
// Datetime property that gets/sets acquired date
public DateTime AcquiredDate { get; set; }
// Float property that gets/sets purchase price
public float? PurchasePrice { get; set; }
//Float property that gets/sets current value
public float? CurrentValue { get; set; }
// Foreign Key
// Int property that gets/sets condition id
public int? ConditionId { get; set; }
// Foreign Key
// Int property that gets/sets location id
public int? LocationId { get; set; }
// Datetime property that gets/sets retired date
public DateTime RetiredDate { get; set; }
//String property that gets/sets description
public string Description { get; set; }
// Foreign Key
// Collection of asset files
public ICollection<AssetFile> AssetFiles { get; set; }
// Navigation Property
public Category Category { get; set; }
// Navigation Property
public Manufacturer Manufacturer { get; set; }
// Navigation Property
public Condition Condition { get; set; }
//Navigation Property
public Location Location { get; set; }
}
我缺少的数据是 CategoryName、ManufacturerName、ConditionName LocationName,以及连接到资产的所有资产文件
当我在邮递员中执行正常的获取请求时,我可以毫无问题地获取所有数据。但是通过 ID 获取时,上面的字段丢失了,我不知道为什么
任何指导将不胜感激
更新:
assetFile DTO
public class AssetFileDto
{
// Int property that gets/sets the id
public int Id { get; set; }
// Byte property that gets/sets the files
public byte[] Files { get; set; }
// String property that gets/sets the name
public string Name { get; set; }
// String property that gets/sets the mime type
public string MimeType { get; set; }
}
assetFile.cs
public class AssetFile
{
// Int property that gets/sets the id
public int? Id { get; set; }
// Byte property that gets/sets the File
public byte[] File { get; set; }
// String property that gets/sets Name
public string Name { get; set; }
// String property that gets/sets the mime type
public string MimeType { get; set; }
//Int property that gets/sets the asset id
public int AssetId { get; set; }
// Asset navigation property
public Asset Asset { get; set; }
}
您需要扩展您的映射配置文件。 AutoMapper 无法为您解决所有问题。它只会自动映射具有相同名称的属性。
例如,如果您想要 CategoryName
CreateMap<Asset, AssetDto>()
.ForMember(x => x.CategoryName, x => x.MapFrom(y => y.Category.Name))
.ReverseMap();
这与这个问题没有直接关系,但我建议你使用ProjectTo这样你只select你需要的字段,而不是将它们加载到内存中然后过滤。
我通过将您的实体添加到本地项目来检查它是否有效。
我更改的一些内容是针对演示的一部分,因此您只需注意更改,然后将相关的应用到您的代码中。
控制器/服务
注入IMapper
并使用ProjectTo
(如果您还没有,则需要 AutoMapper.Extensions.Microsoft.DependencyInjection
)。
private readonly IMapper Mapper;
/* Inject into controller constructor */
public async Task<IActionResult> GetAsset(int key)
{
var asset = await Db.Assets
.Where(i => i.Id == key)
.ProjectTo<AssetDto>(Mapper.ConfigurationProvider)
.FirstOrDefaultAsync();
if (asset == null) return NotFound();
return Json(asset);
}
AssetFileDto
如果您希望它与您的 AssetFile
匹配,Files
应该被称为 File
。
public byte[] File { get; set; }
映射配置文件
然后您应该有一个看起来像这样的映射配置文件
CreateMap<Asset, AssetDto>()
.ForMember(x => x.Files, x => x.MapFrom(y => y.AssetFiles));
CreateMap<AssetFile, AssetFileDto>();
我在 ASP.NET CORE api 中使用 EF Core 和 Auto Mapper,我有点难以理解为什么我在获取数据时没有获取所有数据身份证.
当我调试并查看数据时,它全部存在于变量中,但当它到达自动映射器部分时,就像某些数据被忽略了一样。
如何获取所有对应Id的数据
这是我的 GetAsset by Id 方法。
[HttpGet("{key:int}", Name = "getAsset")]
[EnableQuery]
public async Task<ActionResult<AssetDto>> GetAsset(int key)
{
var asset = await _context.Assets.Include(c => c.Category)
.Include(m => m.Manufacturer)
.Include(c => c.Condition)
.Include(l => l.Location)
.Include(f => f.AssetFiles)
.FirstOrDefaultAsync(i => i.Id == key);
if (asset == null) return NotFound();
var assetDto = _mapper.Map<AssetDto>(asset);
return assetDto;
}
这是我使用 automapper 的映射
CreateMap<Asset, AssetDto>().ReverseMap();
这是我的 AssetDTO
public class AssetDto
{ // Get and sets the Id property
public int Id { get; set; }
// Gets and sets the Name Property and sets it to required
[Required]
public string Name { get; set; }
// Gets and sets the CategoryId property
public int CategoryId { get; set; }
// Gets and sets the CategoryName property set it to NotMapped
[NotMapped]
public string CategoryName { get; set; }
// Gets and sets the ManufacturerId property
public int ManufacturerId { get; set; }
// Gets and sets the ManufacturerName property set it to NotMapped
[NotMapped]
public string ManufacturerName { get; set; }
//Gets and sets the Model property
public string Model { get; set; }
//Gets and sets the SerialNumber property
public string SerialNumber { get; set; }
// Gets and sets the PurchasePlace property
public string PurchasePlace { get; set; }
// Gets and sets the Quantity property
public int Quantity { get; set; }
// Gets and sets the AcquiredDate property
public DateTime AcquiredDate { get; set; }
// Gets and sets the PurchasePrice property/
public float PurchasePrice { get; set; }
// Gets and sets the CurrentValue property
public float CurrentValue { get; set; }
//Gets and sets the ConditionId property
public int ConditionId { get; set; }
// Gets and sets the ConditionName property set it to NotMapped/
[NotMapped]
public string ConditionName { get; set; }
// Gets and sets the LocationId property
public int LocationId { get; set; }
// Gets and sets the LocationName property set it to NotMapped
[NotMapped]
public string LocationName { get; set; }
// Gets and sets the RetiredDate property
public DateTime RetiredDate { get; set; }
// Gets and sets the Description property
public string Description { get; set; }
// Gets and sets the Files property set it to NotMapped
[NotMapped]
public ICollection<AssetFileDto> Files { get; set; } <-- updated
}
和我的资产模型
public class Asset
{ // Int property that gets/sets id
public int Id { get; set; }
// String property that gets/sets Name
[Required]
public string Name { get; set; }
//Foreign Key
//Int property that gets/sets category id
public int? CategoryId { get; set; }
// Foreign Key
// Int property that gets/sets Manufacturer id
public int? ManufacturerId { get; set; }
// String property that gets/sets model
public string Model { get; set; }
// String property that gets/sets serial number
public string SerialNumber { get; set; }
// String property that gets/sets purchase place
public string PurchasePlace { get; set; }
//Int property that gets/sets quantity
public int? Quantity { get; set; }
// Datetime property that gets/sets acquired date
public DateTime AcquiredDate { get; set; }
// Float property that gets/sets purchase price
public float? PurchasePrice { get; set; }
//Float property that gets/sets current value
public float? CurrentValue { get; set; }
// Foreign Key
// Int property that gets/sets condition id
public int? ConditionId { get; set; }
// Foreign Key
// Int property that gets/sets location id
public int? LocationId { get; set; }
// Datetime property that gets/sets retired date
public DateTime RetiredDate { get; set; }
//String property that gets/sets description
public string Description { get; set; }
// Foreign Key
// Collection of asset files
public ICollection<AssetFile> AssetFiles { get; set; }
// Navigation Property
public Category Category { get; set; }
// Navigation Property
public Manufacturer Manufacturer { get; set; }
// Navigation Property
public Condition Condition { get; set; }
//Navigation Property
public Location Location { get; set; }
}
我缺少的数据是 CategoryName、ManufacturerName、ConditionName LocationName,以及连接到资产的所有资产文件
当我在邮递员中执行正常的获取请求时,我可以毫无问题地获取所有数据。但是通过 ID 获取时,上面的字段丢失了,我不知道为什么
任何指导将不胜感激
更新:
assetFile DTO
public class AssetFileDto
{
// Int property that gets/sets the id
public int Id { get; set; }
// Byte property that gets/sets the files
public byte[] Files { get; set; }
// String property that gets/sets the name
public string Name { get; set; }
// String property that gets/sets the mime type
public string MimeType { get; set; }
}
assetFile.cs
public class AssetFile
{
// Int property that gets/sets the id
public int? Id { get; set; }
// Byte property that gets/sets the File
public byte[] File { get; set; }
// String property that gets/sets Name
public string Name { get; set; }
// String property that gets/sets the mime type
public string MimeType { get; set; }
//Int property that gets/sets the asset id
public int AssetId { get; set; }
// Asset navigation property
public Asset Asset { get; set; }
}
您需要扩展您的映射配置文件。 AutoMapper 无法为您解决所有问题。它只会自动映射具有相同名称的属性。
例如,如果您想要 CategoryName
CreateMap<Asset, AssetDto>()
.ForMember(x => x.CategoryName, x => x.MapFrom(y => y.Category.Name))
.ReverseMap();
这与这个问题没有直接关系,但我建议你使用ProjectTo这样你只select你需要的字段,而不是将它们加载到内存中然后过滤。
我通过将您的实体添加到本地项目来检查它是否有效。 我更改的一些内容是针对演示的一部分,因此您只需注意更改,然后将相关的应用到您的代码中。
控制器/服务
注入IMapper
并使用ProjectTo
(如果您还没有,则需要 AutoMapper.Extensions.Microsoft.DependencyInjection
)。
private readonly IMapper Mapper;
/* Inject into controller constructor */
public async Task<IActionResult> GetAsset(int key)
{
var asset = await Db.Assets
.Where(i => i.Id == key)
.ProjectTo<AssetDto>(Mapper.ConfigurationProvider)
.FirstOrDefaultAsync();
if (asset == null) return NotFound();
return Json(asset);
}
AssetFileDto
如果您希望它与您的 AssetFile
匹配,Files
应该被称为 File
。
public byte[] File { get; set; }
映射配置文件
然后您应该有一个看起来像这样的映射配置文件
CreateMap<Asset, AssetDto>()
.ForMember(x => x.Files, x => x.MapFrom(y => y.AssetFiles));
CreateMap<AssetFile, AssetFileDto>();