Entity framework 将具有实体引用的实体映射到DTO cnot,并返回被引用实体的值-.NET Core,AutoMapper

Entity framework 将具有实体引用的实体映射到DTO cnot,并返回被引用实体的值-.NET Core,AutoMapper,entity-framework,asp.net-core,automapper,Entity Framework,Asp.net Core,Automapper,最近我创建了一个实体,它与另一个实体有一对一的关系。我试图通过在API GET端点(该实体的)中使用DTO类来检索主实体的所有值和被引用实体的所有值,但收效甚微 对于其他一些实体,我创建了几个DTO类,这些类工作正常,但是这些其他实体没有我想要获取其值的引用实体 一对一(FK)关系设置如下: 主要实体: public class Commodity { public Commodity() { } public long CommodityID { get; s

最近我创建了一个实体,它与另一个实体有一对一的关系。我试图通过在API GET端点(该实体的)中使用DTO类来检索主实体的所有值和被引用实体的所有值,但收效甚微

对于其他一些实体,我创建了几个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; }
}
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; }
}
[HttpGet]
public IActionResult GetCommodities()
{
    var Commodities = this.Context.Commodity
        .Include(i => i.OmsCommodityMaterial);
    var commoditeDTO = _mapper.Map<IList<CommodityViewModel>>(Commodities);
    return Ok(commoditeDTO);
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        this.CreateMap<Commodity, CommodityViewModel>();
        this.CreateMap<CommodityViewModel, Commodity>();
    }
}
引用的实体:

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; }
}
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; }
}
[HttpGet]
public IActionResult GetCommodities()
{
    var Commodities = this.Context.Commodity
        .Include(i => i.OmsCommodityMaterial);
    var commoditeDTO = _mapper.Map<IList<CommodityViewModel>>(Commodities);
    return Ok(commoditeDTO);
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        this.CreateMap<Commodity, CommodityViewModel>();
        this.CreateMap<CommodityViewModel, Commodity>();
    }
}
使用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);
});
这很好,但是我不想在端点中直接使用实体类,而且我不想使用(引用的)实体的所有字段。 在我的其他一些端点中,我使用
AutoMapper
将实体映射到DTO类/视图模型。我原以为为
GET
也这样做会相当简单,但我似乎无法让它工作

我尝试将
商品
DTO映射到我的
商品/oms商品
,如下所示:

// GET: api/commodities
[HttpGet]
public async Task<IEnumerable<Commodity>> GetCommodities()
{
    return await this.Context.Commodity
        .Include(i => i.OmsCommodityMaterial)
        .ToListAsync();
}
DTO类:

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; }
}
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; }
}
[HttpGet]
public IActionResult GetCommodities()
{
    var Commodities = this.Context.Commodity
        .Include(i => i.OmsCommodityMaterial);
    var commoditeDTO = _mapper.Map<IList<CommodityViewModel>>(Commodities);
    return Ok(commoditeDTO);
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        this.CreateMap<Commodity, CommodityViewModel>();
        this.CreateMap<CommodityViewModel, Commodity>();
    }
}
已调整的GET端点:

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; }
}
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; }
}
[HttpGet]
public IActionResult GetCommodities()
{
    var Commodities = this.Context.Commodity
        .Include(i => i.OmsCommodityMaterial);
    var commoditeDTO = _mapper.Map<IList<CommodityViewModel>>(Commodities);
    return Ok(commoditeDTO);
}
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        this.CreateMap<Commodity, CommodityViewModel>();
        this.CreateMap<CommodityViewModel, Commodity>();
    }
}
也许我做了一些明显的错误,但经过几次测试后,我似乎无法找到答案。也许我应该对引用的实体而不是
进行
连接
。包括

顺便说一下,我使用了以下教程作为参考:

您必须明确配置映射器,使其能够从以下位置获取映射值:

this.CreateMap<Commodity, CommodityViewModel>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(m => m.OmsCommodityMaterial.Name));
this.CreateMap()
.ForMember(dest=>dest.Name,opt=>opt.MapFrom(m=>m.omsmoditymaterial.Name));

您必须明确地配置映射器,使其能够从以下位置获取映射值:

this.CreateMap<Commodity, CommodityViewModel>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(m => m.OmsCommodityMaterial.Name));
this.CreateMap()
.ForMember(dest=>dest.Name,opt=>opt.MapFrom(m=>m.omsmoditymaterial.Name));

AutoMapper按约定映射属性。对于相关对象,该约定是在导航属性名称前加前缀。这就是AutoMapper所称的投影。例如,如果DTO属性名为
OMSComodityMaterialName
,它将自动映射
OMSComodityMaterial.Name
中的值。因为,属性只是
Name
,但是,您必须明确地告诉AutoMapper如何处理@AlexRiabov在这里建议的映射。太好了!正是我想要的。谢谢。AutoMapper按约定映射属性。对于相关对象,该约定是在导航属性名称前加前缀。这就是AutoMapper所称的投影。例如,如果DTO属性名为
OMSComodityMaterialName
,它将自动映射
OMSComodityMaterial.Name
中的值。因为,属性只是
Name
,但是,您必须明确地告诉AutoMapper如何处理@AlexRiabov在这里建议的映射。太好了!正是我想要的。非常感谢。