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: EntityQueryable
1 -> List
1 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[[<>f__AnonymousType1
3[[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__AnonymousType1
3 -> DtoAsset <>f__AnonymousType1
3[[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 , List
1 , 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();
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.