代码之家  ›  专栏  ›  技术社区  ›  Nicolas

将实体引用为DTO的实体映射为不返回引用实体的值的实体-.NET核心,automapper

  •  0
  • Nicolas  · 技术社区  · 6 年前

    最近,我创建了一个与另一个实体有一对一关系的实体。我试图通过在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; }
    }
    

    通过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 检索 商品 实体,也包括(相关/引用的)的所有值 OmsCommodity 实体。

    我是这样做的:

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

    这很好,但是我不想直接在端点中使用实体类,而且我不想使用(引用的)实体的所有字段。 在我使用的其他端点中 AutoMapper 用于将我的实体映射到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);
    }
    

    这将正确返回商品实体的值/字段,但是引用的值( OMS公用 )全部返回空值。

    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 回复  |  直到 6 年前
        1
  •  2
  •   Alex Riabov Vikrant    6 年前

    您必须显式地配置映射器,以便从中获取映射值:

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