![](/img/trans.png)
[英]how to map expression<func<Entity,DTO>> with automapper
[英]How to use AutoMapper to unflatten DTO to entity/object property
这可能是一个非常基本的问题,请原谅我对 AutoMapper 的无知。 我试图从文档和其他 SO 问题中找出答案,但到目前为止都失败了。 也许我正在尝试使用 AutoMapper 做一些我不应该做的事情。 我想从展平的 DTO 为对象属性设置一个值。
鉴于这些;
public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
public int ColourId { get; set; }
public Colour Colour { get; set; }
}
public class Colour
{
public int Id { get; set; }
public string Name { get; set; }
}
public class FruitDto
{
public string Name { get; set; }
public string ColourName { get; set; }
}
我可以创建一个扁平的 DTO 没问题,
var db = _serviceScopeFactory.CreateScope()
.ServiceProvider.GetService<FruitDb>();
var fruitDtos = db.Fruits.ProjectTo<FruitDto>(_mapper.ConfigurationProvider);
foreach (var dto in fruitDtos)
{
Console.WriteLine($"db fruit {dto.Name} = {dto.ColourName}");
}
但是当我尝试从 DTO 映射回来时,我需要做什么来获取水果对象颜色属性集和 Colour.Name 集并不明显。
var exampleDto = new FruitDto()
{
Name = "lime",
ColourName = "green"
};
var exampleFruit = _mapper.Map<FruitDto, Fruit>(exampleDto);
Console.WriteLine($"example fruit {exampleFruit.Name} = {exampleFruit.Colour?.Name}");
让 AutoMapper 将 exampleFruit.Colour 设置为一个新的 Color 实例并设置 Name 属性的正确方法是什么(这个问题的扩展,一旦设置,如果颜色已经存在,我应该如何设置 colour.Id 属性?数据库)?
这是上面片段的完整示例;
using System;
using System.Threading;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace EntityFrameworkAutomapConsole
{
public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
public int ColourId { get; set; }
public Colour Colour { get; set; }
}
public class Colour
{
public int Id { get; set; }
public string Name { get; set; }
}
public class FruitDto
{
public string Name { get; set; }
public string ColourName { get; set; }
}
class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddAutoMapper(typeof(AutoMapperProfile));
services.AddDbContext<FruitDb>(options =>
{
options.UseNpgsql("conn string here");
});
services.AddHostedService<Worker>();
});
}
public class Worker : BackgroundService
{
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IMapper _mapper;
public Worker(
IServiceScopeFactory serviceScopeFactory,
IMapper mapper)
{
_serviceScopeFactory = serviceScopeFactory;
_mapper = mapper;
var fruitDb = _serviceScopeFactory.CreateScope()
.ServiceProvider.GetService<FruitDb>();
fruitDb.Database.EnsureCreated();
}
protected override async Task ExecuteAsync(CancellationToken cancel)
{
var db = _serviceScopeFactory.CreateScope()
.ServiceProvider.GetService<FruitDb>();
var fruitDtos = db.Fruits.ProjectTo<FruitDto>(_mapper.ConfigurationProvider);
foreach (var dto in fruitDtos)
{
Console.WriteLine($"db fruit {dto.Name} = {dto.ColourName}");
}
var exampleDto = new FruitDto()
{
Name = "lime",
ColourName = "green"
};
var exampleFruit = _mapper.Map<FruitDto, Fruit>(exampleDto);
Console.WriteLine($"example fruit {exampleFruit.Name} = {exampleFruit.Colour?.Name}");
}
}
public class FruitDb : DbContext
{
public FruitDb(DbContextOptions options)
: base(options)
{
}
public DbSet<Fruit> Fruits { get; set; }
public DbSet<Colour> Colours { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.HasDefaultSchema("public");
builder.Entity<Fruit>()
.HasIndex(f => f.Id)
.IsUnique();
builder.Entity<Colour>()
.HasIndex(c => c.Id)
.IsUnique();
base.OnModelCreating(builder);
}
}
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<FruitDto, Fruit>();
CreateMap<Fruit, FruitDto>();
}
}
}
感谢@lucian-bargaoanu,超级简单的评论。 我在文档中错过了这一点。 所以我只需要在我的配置文件中使用 ReverseMap() 并删除显式FruitDto
到Fruit
映射。
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<FruitDto, Fruit>();
CreateMap<Fruit, FruitDto>();
}
}
变成
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<Fruit, FruitDto>().ReverseMap();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.