DotNet Core 3.1 Web API + AutoMapper:mapper.map 方法出错
DotNet Core 3.1 Web API + AutoMapper: Error in mapper.map method
我在 ASP.Net Core 3 Web API 项目中使用 Nuget 包 AutoMapper.Extensions.Microsoft.DependencyInjection 版本 7.0.0。
当我使用 Map() 方法时...
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper<IEnumerable<School>, IEnumerable<SchoolForListDto>>.Map(schools);
...我收到以下错误消息:
Type arguments in method IMapper.Map<TDestination>(object) cannot be inferred from the usage. Try specifying the type arguments explicitly.
完整代码:
Models/Holder.cs
using System;
using System.Collections.Generic;
namespace SchoolApi.Models
{
public class Holder
{
public string Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public virtual ICollection<School> Schools { get; set; }
}
}
Models/School.cs
using System;
using System.Collections.Generic;
namespace SchoolApi.Models
{
public class School
{
public string Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public string WebSite { get; set; }
public string Address { get; set; }
public string HolderId { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public virtual Holder Holder { get; set; }
}
}
Data/DataContext.cs
using Microsoft.EntityFrameworkCore;
using SchoolApi.Models;
namespace SchoolApi.Data
{
public class DataContext : DbContext
{
public DbSet<Holder> Holders { get; set; }
public DbSet<School> Schools { get; set; }
public DataContext(DbContextOptions<DataContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
}
Data/IGenericRepository
using System.Collections.Generic;
using System.Threading.Tasks;
namespace SchoolApi.Data
{
public interface IGenericRepository<TEntity> where TEntity : class
{
void Add(TEntity entity);
void Delete(TEntity entity);
Task<TEntity> Get(object id);
Task<IEnumerable<TEntity>> GetAll();
Task<bool> SaveAll();
void Update(TEntity entity);
}
}
Data/GenericRepository
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace SchoolApi.Data
{
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
private readonly DataContext _dataContext;
private readonly string _entityName = typeof(TEntity).FullName;
public GenericRepository(DataContext dataContext)
{
_dataContext = dataContext;
}
public void Add(TEntity entity)
{
_dataContext.Set<TEntity>().Add(entity);
}
public void Delete(TEntity entity)
{
_dataContext.Set<TEntity>().Remove(entity);
}
public async Task<TEntity> Get(object id)
{
TEntity entity = await _dataContext.Set<TEntity>().FindAsync(id);
return entity;
}
public async Task<IEnumerable<TEntity>> GetAll()
{
IEnumerable<TEntity> entities = await _dataContext.Set<TEntity>().ToListAsync();
return entities;
}
public async Task<bool> SaveAll()
{
int result = await _dataContext.SaveChangesAsync();
return result > 0;
}
public void Update(TEntity entity)
{
_dataContext.Set<TEntity>().Update(entity);
}
}
}
Dtos/SchoolForListDto.cs
namespace SchoolApi.Dtos
{
public class SchoolForListDto
{
public string Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public string HolderName { get; set; }
}
}
Helpers/AutoMapperProfiles
using AutoMapper;
using SchoolApi.Dtos;
using SchoolApi.Models;
namespace SchoolApi.Helpers
{
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
CreateMap<School, SchoolForListDto>()
.ForMember(dest => dest.HolderName, opt => opt.MapFrom(src => src.Holder.Name));
}
}
}
Startup.cs
using AutoMapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SchoolApi.Data;
using SchoolApi.Models;
namespace SchoolApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddCors();
services.AddDbContext<DataContext>(options => options.UseLazyLoadingProxies().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddAutoMapper(typeof(Startup));
services.AddScoped<IGenericRepository<School>, GenericRepository<School>>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(x => x.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Controllers/SchoolController.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SchoolApi.Data;
using SchoolApi.Dtos;
using SchoolApi.Models;
namespace SchoolApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SchoolController : ControllerBase
{
private readonly IGenericRepository<School> _repository;
private readonly IMapper _mapper;
private readonly ILogger<SchoolController> _logger;
public SchoolController(IGenericRepository<School> repository, IMapper mapper, ILogger<SchoolController> logger)
{
_repository = repository;
_mapper = mapper;
_logger = logger;
}
[HttpGet]
public async Task<IActionResult> GetAll()
{
IEnumerable<School> schools = await _repository.GetAll();
// The error occurs on the following line
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper<IEnumerable<School>, IEnumerable<SchoolForListDto>>.Map(schools);
return Ok(schoolsToReturn);
}
[HttpGet("{id}")]
public async Task<IActionResult> Get([FromRoute] string id)
{
School school = await _repository.Get(id);
SchoolForListDto schoolToReturn = _mapper.Map<SchoolForListDto>(school);
return Ok(schoolToReturn);
}
}
}
这些是我正在使用的软件包:
- AutoMapper.Extensions.Microsoft.DependencyInjection(版本 7.0.0)
- Microsoft.AspNetCore.Mvc.NewtonsoftJson(版本 3.1.4)
- Microsoft.EntityFrameworkCore(版本 3.1.4)
- Microsoft.EntityFrameworkCore.设计(版本 3.1.4)
- Microsoft.EntityFrameworkCore.代理(版本 3.1.4)
- Microsoft.EntityFrameworkCore.关系型(版本 3.1.4)
- Microsoft.EntityFrameworkCore.SqlServer(版本 3.1.4)
目标框架:DotNet Core 3.1
IDE: Visual Studio 代码
所以:Windows 10
GitHub 存储库:https://github.com/jmcandia/SchoolApi
感谢@TimothyMacharia 的建议。它有效地帮助我解决了问题。
我更改了这段代码...
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper<IEnumerable<School>, IEnumerable<SchoolForListDto>>.Map(schools);
...对于这个,它起作用了。
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper.Map<IEnumerable<SchoolForListDto>>(schools);
我在 ASP.Net Core 3 Web API 项目中使用 Nuget 包 AutoMapper.Extensions.Microsoft.DependencyInjection 版本 7.0.0。
当我使用 Map() 方法时...
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper<IEnumerable<School>, IEnumerable<SchoolForListDto>>.Map(schools);
...我收到以下错误消息:
Type arguments in method IMapper.Map<TDestination>(object) cannot be inferred from the usage. Try specifying the type arguments explicitly.
完整代码:
Models/Holder.cs
using System;
using System.Collections.Generic;
namespace SchoolApi.Models
{
public class Holder
{
public string Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public virtual ICollection<School> Schools { get; set; }
}
}
Models/School.cs
using System;
using System.Collections.Generic;
namespace SchoolApi.Models
{
public class School
{
public string Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public string WebSite { get; set; }
public string Address { get; set; }
public string HolderId { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public virtual Holder Holder { get; set; }
}
}
Data/DataContext.cs
using Microsoft.EntityFrameworkCore;
using SchoolApi.Models;
namespace SchoolApi.Data
{
public class DataContext : DbContext
{
public DbSet<Holder> Holders { get; set; }
public DbSet<School> Schools { get; set; }
public DataContext(DbContextOptions<DataContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
}
Data/IGenericRepository
using System.Collections.Generic;
using System.Threading.Tasks;
namespace SchoolApi.Data
{
public interface IGenericRepository<TEntity> where TEntity : class
{
void Add(TEntity entity);
void Delete(TEntity entity);
Task<TEntity> Get(object id);
Task<IEnumerable<TEntity>> GetAll();
Task<bool> SaveAll();
void Update(TEntity entity);
}
}
Data/GenericRepository
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace SchoolApi.Data
{
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
private readonly DataContext _dataContext;
private readonly string _entityName = typeof(TEntity).FullName;
public GenericRepository(DataContext dataContext)
{
_dataContext = dataContext;
}
public void Add(TEntity entity)
{
_dataContext.Set<TEntity>().Add(entity);
}
public void Delete(TEntity entity)
{
_dataContext.Set<TEntity>().Remove(entity);
}
public async Task<TEntity> Get(object id)
{
TEntity entity = await _dataContext.Set<TEntity>().FindAsync(id);
return entity;
}
public async Task<IEnumerable<TEntity>> GetAll()
{
IEnumerable<TEntity> entities = await _dataContext.Set<TEntity>().ToListAsync();
return entities;
}
public async Task<bool> SaveAll()
{
int result = await _dataContext.SaveChangesAsync();
return result > 0;
}
public void Update(TEntity entity)
{
_dataContext.Set<TEntity>().Update(entity);
}
}
}
Dtos/SchoolForListDto.cs
namespace SchoolApi.Dtos
{
public class SchoolForListDto
{
public string Id { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public string HolderName { get; set; }
}
}
Helpers/AutoMapperProfiles
using AutoMapper;
using SchoolApi.Dtos;
using SchoolApi.Models;
namespace SchoolApi.Helpers
{
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
CreateMap<School, SchoolForListDto>()
.ForMember(dest => dest.HolderName, opt => opt.MapFrom(src => src.Holder.Name));
}
}
}
Startup.cs
using AutoMapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SchoolApi.Data;
using SchoolApi.Models;
namespace SchoolApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddCors();
services.AddDbContext<DataContext>(options => options.UseLazyLoadingProxies().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddAutoMapper(typeof(Startup));
services.AddScoped<IGenericRepository<School>, GenericRepository<School>>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(x => x.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Controllers/SchoolController.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SchoolApi.Data;
using SchoolApi.Dtos;
using SchoolApi.Models;
namespace SchoolApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class SchoolController : ControllerBase
{
private readonly IGenericRepository<School> _repository;
private readonly IMapper _mapper;
private readonly ILogger<SchoolController> _logger;
public SchoolController(IGenericRepository<School> repository, IMapper mapper, ILogger<SchoolController> logger)
{
_repository = repository;
_mapper = mapper;
_logger = logger;
}
[HttpGet]
public async Task<IActionResult> GetAll()
{
IEnumerable<School> schools = await _repository.GetAll();
// The error occurs on the following line
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper<IEnumerable<School>, IEnumerable<SchoolForListDto>>.Map(schools);
return Ok(schoolsToReturn);
}
[HttpGet("{id}")]
public async Task<IActionResult> Get([FromRoute] string id)
{
School school = await _repository.Get(id);
SchoolForListDto schoolToReturn = _mapper.Map<SchoolForListDto>(school);
return Ok(schoolToReturn);
}
}
}
这些是我正在使用的软件包: - AutoMapper.Extensions.Microsoft.DependencyInjection(版本 7.0.0) - Microsoft.AspNetCore.Mvc.NewtonsoftJson(版本 3.1.4) - Microsoft.EntityFrameworkCore(版本 3.1.4) - Microsoft.EntityFrameworkCore.设计(版本 3.1.4) - Microsoft.EntityFrameworkCore.代理(版本 3.1.4) - Microsoft.EntityFrameworkCore.关系型(版本 3.1.4) - Microsoft.EntityFrameworkCore.SqlServer(版本 3.1.4)
目标框架:DotNet Core 3.1 IDE: Visual Studio 代码 所以:Windows 10 GitHub 存储库:https://github.com/jmcandia/SchoolApi
感谢@TimothyMacharia 的建议。它有效地帮助我解决了问题。
我更改了这段代码...
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper<IEnumerable<School>, IEnumerable<SchoolForListDto>>.Map(schools);
...对于这个,它起作用了。
IEnumerable<SchoolForListDto> schoolsToReturn = _mapper.Map<IEnumerable<SchoolForListDto>>(schools);