Сопоставление сущности со ссылкой на сущность в узел DTO, возвращающий значения ссылочной сущности - .NET Core, AutoMapper - PullRequest
0 голосов
/ 02 июля 2018

Недавно я создал сущность, которая имеет отношение один к одному с другой сущностью. Я пытаюсь получить все значения основной сущности И все значения ссылочной сущности, используя класс 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

1 Ответ

0 голосов
/ 02 июля 2018

Вы должны явно настроить маппер, где он должен получить значение для маппинга:

this.CreateMap<Commodity, CommodityViewModel>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(m => m.OmsCommodityMaterial.Name));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...