Недавно я создал сущность, которая имеет отношение один к одному с другой сущностью. Я пытаюсь получить все значения основной сущности И все значения ссылочной сущности, используя класс DTO в моей конечной точке GET API (этой сущности), но с небольшим успехом
Для некоторых других сущностей я создал несколько классов DTO, и они работают нормально, однако у этих других сущностей нет ссылочной сущности, значения которой я хочу получить.
Отношение один к одному (FK) устанавливается следующим образом:
Основное лицо:
public class Commodity
{
public Commodity()
{
}
public long CommodityID { get; set; }
public long OMSCommodityMaterialID { get; set; }
public decimal? SpecficWeight { get; set; }
public virtual OmsCommodityMaterial OmsCommodityMaterial { get; set; }
}
Ссылочная сущность:
public class OmsCommodityMaterial
{
public OmsCommodityMaterial()
{
}
public long? CommodityMaterialID { get; set; }
public string Name { get; set; }
public long? SortOrder { get; set; }
[JsonIgnore]
public virtual Commodity Commodity { get; set; }
}
С помощью FLUENT API я определяю взаимно-однозначное отношение:
modelBuilder.Entity<Commodity>(entity =>
{
entity.Property(e => e.CommodityID)
.HasColumnName("CommodityID")
.ValueGeneratedOnAdd();
entity.Property(e => e.OMSCommodityMaterialID)
.HasColumnName("OMSCommodityMaterialID");
entity.Property(e => e.SpecficWeight)
.HasColumnName("SpecficWeight")
.HasColumnType("decimal(18, 2)");
entity.HasOne(a => a.OmsCommodityMaterial)
.WithOne(b => b.Commodity)
.HasForeignKey<Commodity>(b => b.OMSCommodityMaterialID);
});
Теперь в моей Commodity
конечной точке (контроллере) я хочу иметь оператор GET
, который извлекает все поля / значения объекта Commodity
, но также и все значения (связанные / ссылающиеся) OmsCommodity
сущность.
Я делаю это следующим образом:
// GET: api/commodities
[HttpGet]
public async Task<IEnumerable<Commodity>> GetCommodities()
{
return await this.Context.Commodity
.Include(i => i.OmsCommodityMaterial)
.ToListAsync();
}
Это работает нормально, однако я не хочу использовать свои классы сущностей непосредственно в моей конечной точке, и, кроме того, я не хочу использовать все поля (ссылочной) сущности.
В некоторых других моих конечных точках я использовал AutoMapper
для сопоставления моих сущностей с классом DTO / ViewModel. Я думал, что это будет довольно просто сделать и для GET
, но я не могу заставить его работать.
Я попытался сопоставить Commodity
DTO с моим Commodity/OmsCommodity
следующим образом:
Класс DTO:
public class CommodityDTO
{
public long CommodityID { get; set; }
public long OMSCommodityMaterialID { get; set; }
public decimal? SpecficWeight { get; set; }
// Referenced entity part
public string Name { get; set; }
public long? SortOrder { get; set; }
}
(скорректированная) конечная точка GET:
[HttpGet]
public IActionResult GetCommodities()
{
var Commodities = this.Context.Commodity
.Include(i => i.OmsCommodityMaterial);
var commoditeDTO = _mapper.Map<IList<CommodityViewModel>>(Commodities);
return Ok(commoditeDTO);
}
Это возвращает значения / поля сущности Commodity правильно, однако все ссылочные значения (OmsCommodity
) возвращают NULL.
Настройка AutoMapper выглядит следующим образом:
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
this.CreateMap<Commodity, CommodityViewModel>();
this.CreateMap<CommodityViewModel, Commodity>();
}
}
Возможно, я делаю что-то явно не так, но после нескольких тестов я не могу понять это. Возможно, я должен просто сделать JOIN
на объекте, на который ссылаемся, вместо .Include
?
Кстати, я использовал следующее руководство:
http://jasonwatmore.com/post/2018/06/26/aspnet-core-21-simple-api-for-authentication-registration-and-user-management