如何使用AutoMapper将DTO取消填充到实体/对象属性



这可能是一个非常基本的问题,请原谅我对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映射回来时,我不清楚我需要做什么来获得水果对象颜色属性集和颜色。名称集。

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树立榜样的正确方法是什么?Fruit。Colour到一个新的Colour实例,该实例设置了Name属性(这个问题的扩展,一旦设置了,如果颜色已经存在于数据库中,我应该如何设置color.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((,并删除显式的FruitDtoFruit映射。

public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<FruitDto, Fruit>();
CreateMap<Fruit, FruitDto>();
}
}

成为

public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<Fruit, FruitDto>().ReverseMap();
}
}

最新更新