Home > Back-end >  Exception when I try to pass query result to Dto object "Error mapping types"
Exception when I try to pass query result to Dto object "Error mapping types"

Time:05-07

I am trying to make a basic query to my database with Linq-to-SQL

The query is done correctly, I tried it with LinqPad and it works, the problem (I think so, I'm not an expert) is when trying to pass the result of the query to my DTO object DtoAsset

I googled it but I can't understand the reason for the error.

AutoMapper.AutoMapperMappingException: Error mapping types.

Mapping types: EntityQueryable1 -> List1 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[[<>f__AnonymousType13[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.List`1[[API.Dtos.DtoAsset, API, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] ---> AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.

Mapping types: <>f__AnonymousType13 -> DtoAsset <>f__AnonymousType13[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] -> API.Dtos.DtoAsset at lambda_method19(Closure , <>f__AnonymousType13 , DtoAsset , ResolutionContext ) at lambda_method18(Closure , Object , List1 , ResolutionContext ) --- End of inner exception stack trace ---
at lambda_method18(Closure , Object , List`1 , ResolutionContext )
at API.Controllers.InventoryController.SearhInventory() in C:\WebApp\backend\API\Controllers\InventoryControllers.cs:line 47
at lambda_method6(Closure , Object )

Endpoint

[HttpGet("Search/")]
public async Task<ActionResult<List<DtoAsset>>> SearhInventory()
{
    var query =
        from a in context.Assets
        join i in context.Inventories
        on a.inventory_id equals i.inventory_id
        where a.inventory_id == 1
        select new { asset_id = a.asset_id, name = a.name, inventory_id = a.inventory_id };

    await query.ToListAsync();

    List<DtoAsset> dto = mapper.Map<List<DtoAsset>>(query);
    return dto;
}

Mapper

namespace API.Map
{
    public class AutoMapper : Profile
    {
        public AutoMapper()
        {
            #region Inventory
            CreateMap<Inventory, DtoInventory>().ReverseMap();
            //Create
            CreateMap<DtoInventoryCreate, Inventory>();
            #endregion

            #region Asset
            CreateMap<Asset, DtoAsset>().ReverseMap();
            //Create
            CreateMap<DtoAssetCreate, Asset>();

            #endregion
        }
    }
}

Models

public class Asset
{
    public int asset_id { get; set; }
    public int code { get; set; }
    public string name { get; set; }
    public int inventory_id { get; set; }
    public Inventory Inventory { get; set; }
}

public class Inventory
{
    public int inventory_id { get; set; }
    public string name { get; set; }
    public string location { get; set; }
    public int status { get; set; }
    public DateTime? created_date { get; set; }
    public List<Asset> Assets { get; set; }

}

DTOs

namespace API.Dtos
{
    public class DtoAsset
    {
        public int asset_id { get; set; }
        public int code { get; set; }
        public string name { get; set; }
        public int inventory_id { get; set; }
    }

    public class DtoInventory
    {
        public int inventory_id { get; set; }
        public string name { get; set; }
        public string location { get; set; }
        public bool status { get; set; }
        public DateTime created_date { get; set; }
        public List<Asset> Assets { get; set; }
    }
}

Program

using System.Text.Json.Serialization;
using API.Data;
using Microsoft.EntityFrameworkCore;

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      policy =>
                      {
                          policy.WithOrigins("http://localhost:3000")
                            .AllowAnyMethod()
                            .AllowAnyHeader();
                      });
});
//  AutoMapper
builder.Services.AddAutoMapper(typeof(Program));

// MS SQL Connector start...
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// ...end

builder.Services.AddControllers().AddJsonOptions(
    x => x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
//      SSL Certifitate = Disable
// app.UseHttpsRedirection();

// CORS!
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();

app.MapControllers();

app.Run();

enter image description here enter image description here

CodePudding user response:

Your query.ToList() does not return a list of Assets but a list with new anonymous objects with the same properties as the Asset. What you want is:

query = ... select new Asset { asset_id = a.asset_id, name = a.name, inventory_id = a.inventory_id };

Edit: I just noticed, you also call toList(), but you do not assign the result anywhere.

  • Related