C# 如何使用AutoMapper将DTO取消设置为实体/对象属性

C# 如何使用AutoMapper将DTO取消设置为实体/对象属性,c#,entity-framework-core,automapper,C#,Entity Framework Core,Automapper,这可能是一个相当基本的问题,请原谅我的无知。我试着从文档和其他问题中找出答案,但到目前为止失败了。也许我想用AutoMapper做一些我不应该做的事情。我想在对象属性上设置一个值,从展开的DTO开始 鉴于此, public class Fruit { public int Id { get; set; } public string Name { get; set; } public int ColourId { get; set; } public Colour

这可能是一个相当基本的问题,请原谅我的无知。我试着从文档和其他问题中找出答案,但到目前为止失败了。也许我想用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}");
}
var db=\u serviceScopeFactory.CreateScope()
.ServiceProvider.GetService();
var fruitDtos=db.Fruits.ProjectTo(_mapper.ConfigurationProvider);
foreach(水果中的var dto)
{
Console.WriteLine($“db fruit{dto.Name}={dto.colorname}”);
}
但是,当我尝试从DTO映射回时,我不清楚需要做什么来获得水果对象颜色属性集和color.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}");
var exampleDto=new foultedto()
{
Name=“lime”,
colorName=“绿色”
};
var exampleFruit=\u mapper.Map(exampleDto);
WriteLine($“示例水果{exampleFruit.Name}={exampleFruit.color?.Name}”);
让AutoMapper将exampleFruit.Color设置为具有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>();
        }
    }
}
使用系统;
使用系统线程;
使用System.Threading.Tasks;
使用自动制版机;
使用AutoMapper.QueryableExtensions;
使用Microsoft.EntityFrameworkCore;
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.Extensions.Hosting;
命名空间EntityFrameworkAutoMaconsole
{
公共级水果
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共int colorId{get;set;}
公共颜色{get;set;}
}
公共类颜色
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公共类水果
{
公共字符串名称{get;set;}
公共字符串colorName{get;set;}
}
班级计划
{
公共静态void Main(字符串[]args)
{
CreateHostBuilder(args.Build().Run();
}
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
.ConfigureServices((主机上下文,服务)=>
{
AddAutoMapper(typeof(AutoMapperProfile));
services.AddDbContext(选项=>
{
options.UseNpgsql(“此处为conn字符串”);
});
services.AddHostedService();
});
}
公共班级工作人员:背景服务
{
专用readonly IServiceScopeFactory\u serviceScopeFactory;
专用只读IMapper\u映射器;
公务员(
IServiceScopeFactory服务ScopeFactory,
IMapper(映射器)
{
_serviceScopeFactory=serviceScopeFactory;
_映射器=映射器;
var fruitDb=\u serviceScopeFactory.CreateScope()
.ServiceProvider.GetService();
exportdb.Database.recreated();
}
受保护的覆盖异步任务ExecuteAsync(CancellationToken cancel)
{
var db=\u serviceScopeFactory.CreateScope()
.ServiceProvider.GetService();
var fruitDtos=db.Fruits.ProjectTo(_mapper.ConfigurationProvider);
foreach(水果中的var dto)
{
Console.WriteLine($“db fruit{dto.Name}={dto.colorname}”);
}
var exampleDto=new foultedto()
{
Name=“lime”,
colorName=“绿色”
};
var exampleFruit=\u mapper.Map(exampleDto);
WriteLine($“示例水果{exampleFruit.Name}={exampleFruit.color?.Name}”);
}
}
公共类数据库:DbContext
{
public FroothDB(DbContextOptions选项)
:基本(选项)
{
}
公共数据库集{get;set;}
公共数据库集颜色{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder)
{
builder.hasdaultschema(“公共”);
builder.Entity()
.HasIndex(f=>f.Id)
.IsUnique();
builder.Entity()
.HasIndex(c=>c.Id)
.IsUnique();
基于模型创建(生成器);
}
}
公共类自动映射配置文件:配置文件
{
公共自动映射配置文件()
{
CreateMap();
CreateMap();
}
}
}

感谢@lucian bargaoanu的超级简单评论。我在文件里漏掉了。因此,我只需要在我的配置文件中使用ReverseMap(),并删除显式的
FruitDto
Fruit
映射

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<FruitDto, Fruit>();
        CreateMap<Fruit, FruitDto>();
    }
}
public类AutoMapperProfile:Profile
{
公共自动映射配置文件()
{
CreateMap();
CreateMap();
}
}
变成

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Fruit, FruitDto>().ReverseMap();
    }
}
public类AutoMapperProfile:Profile
{
公共自动映射配置文件()
{
CreateMap().ReverseMap();
}
}