[英]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.