I'm using EF Core and Auto Mapper in an ASP.NET CORE api and I am having a little bit of trouble understanding why I am not getting all my data when I get it by ID.
When I debug and look at the data it is all there in the variable but when it hits the automapper part it is like some data is ignored.
How can I get all the data with the corresponding Id.
this is my method for the 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;
}
Here is my mapping with automapper
CreateMap<Asset, AssetDto>().ReverseMap();
here is my 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
}
and my Asset Model
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; }
}
The data that I am missing is the CategoryName, ManufacturerName, ConditionName LocationName, And All the asset files that are connected to the asset
When I do a normal get request in postman I get all the data no problem. But when getting it by ID the above fields are missing and I don't know why
any guidance would be grateful
Update:
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; }
}
You need to expand on your mapping profile. AutoMapper can't work everything out for you. It only maps the properties with the same names automatically.
For example, if you want
CategoryNameIt's not directly related to this question, but I would recommend that you use ProjectTo so you only select the fields you need, instead of loading them into memory and then filtering.
I checked to see if it worked by added your entities to a local project. Some of the stuff I changed was for part of the demo, so you can just notice the changes and then apply the relevant ones to your code.
Controller / Service
Inject
IMapperand useProjectTo(you'll need
AutoMapper.Extensions.Microsoft.DependencyInjection, if you don't have it already).AssetFileDto
If you want it to match with your
AssetFile,Filesshould be calledFile.Mapping Profile
You should then have a mapping profile that looks something like this