标签: automapper-5

如何使用AutoMapper的新IValueResolver?

我不知道如何IValueResolver在新版本的AutoMapper中使用新界面.也许我在以前版本的AutoMapper中使用它们不正确......

我有很多模型类,其中一些是使用sqlmetal从几个数据库服务器上的几个数据库生成的.

其中一些类具有字符串属性,PublicationCode用于标识订阅,商品或发票或其他任何内容所属的发布.

该发布可以存在于两个系统(旧系统和新系统)中的任何一个系统中,因此我在目标模型类上有一个bool属性,用于指示发布是在旧系统还是新系统中.

使用AutoMapper的旧版本(<5?),我使用的ValueResolver<string, bool>,其采取了PublicationCode作为输入参数,并且返回一个bool指示出版物(旧的或新的系统)的位置.

使用AutoMapper的新版本(5+?),这似乎不再可能.新的IValueResolver需要我拥有的源模型和目标模型的每个组合的唯一实现,src.PublicationCode需要将其解析为dst.IsInNewSystem.

我只是试图以错误的方式使用值解析器吗?有没有更好的办法?我想使用解析器的主要原因是我更喜欢将服务注入到构造函数中,而不必DependencyResolver在代码中使用等(我使用的是Autofac).

目前,我通过以下方式使用它:

// Class from Linq-to-SQL, non-related properties removed.
public class FindCustomerServiceSellOffers {
    public string PublicationCode { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是我拥有的几个数据模型类之一,它包含一个PublicationCode属性).此特定类映射到此视图模型:

public class SalesPitchViewModel {
    public bool IsInNewSystem { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这两个类的映射定义是(其中expression是IProfileExpression),删除了不相关的映射:

expression.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>()
          .ForMember(d => d.IsInNewSystem, o => o.ResolveUsing<PublicationSystemResolver>().FromMember(s => s.PublicationCode));
Run Code Online (Sandbox Code Playgroud)

解析器:

public class PublicationSystemResolver : ValueResolver<string, bool>
{
    private readonly PublicationService _publicationService; …
Run Code Online (Sandbox Code Playgroud)

c# automapper automapper-5

19
推荐指数
1
解决办法
1万
查看次数

使用ProjectTo()时,Mapper未初始化

我在我的项目中使用Automapper 5.2.0.当我ProjectTo()在代码中使用时获取此错误:

Mapper未初始化.使用适当的配置调用Initialize.如果您正试图通过容器或以其它方式使用映射器实例,请确保您不必静态Mapper.Map方法的任何电话,如果你使用ProjectTo或UseAsDataSource扩展方法,确保你在适当的IConfigurationProvider通实例.

服务代码

 public async Task<FreelancerProfileViewModel> GetFreelancerProfile()
    {
        var id = Guid.Parse(_identity.GetUserId());
        var model = await _freelancerProfiles
            .AsNoTracking()
            .Where(_ => _.User.Id == id)
            .ProjectTo<FreelancerProfileViewModel>()
            .FirstAsync();

     //  var viewmodel =  _mapper.Map<FreelancerProfileViewModel>(model);

        return model;
    }
Run Code Online (Sandbox Code Playgroud)

自动映射配置文件

   public class FreelancerDashbordProfile : Profile
{
    private readonly IIdentity _identity;
    public FreelancerDashbordProfile(IIdentity identity)
    {
        _identity = identity;
        var id = Guid.Parse(_identity.GetUserId());
        CreateMap<FreelancerProfile, FreelancerProfileViewModel>()
        .ForMember(_ => _.DoingProjectCount,
            __ => __.MapFrom(_ => _.Projects.Count(project => project.ProjectState == ProjectState.Doing)))

        .ForMember(_ => _.EndProjectCount,
            __ => __.MapFrom(_ …
Run Code Online (Sandbox Code Playgroud)

c# structuremap ioc-container automapper-5

18
推荐指数
2
解决办法
8226
查看次数

EF和Automapper.更新嵌套集合

我试图更新国家实体的嵌套集合(城市).

只是简单的enitities和dto:

// EF Models
public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<City> Cities { get; set; }
}

public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CountryId { get; set; }
    public int? Population { get; set; }

    public virtual Country Country { get; set; }
}

// DTo's
public class CountryData : IDTO …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework-6 automapper-5

13
推荐指数
2
解决办法
7314
查看次数

Automapper v5忽略未映射的属性

以前当我使用Automapper v3.x时,忽略未映射的属性可以通过简单地添加一个.IgnoreUnmappedProperties()看起来像这样的扩展来完成

public static class AutoMapperExtensions
{

public static IMappingExpression<TSource, TDestination> IgnoreUnmappedProperties<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var typeMap = Mapper.FindTypeMapFor<TSource, TDestination>();
    if (typeMap != null)
    {
        foreach (var unmappedPropertyName in typeMap.GetUnmappedPropertyNames())
        {
            expression.ForMember(unmappedPropertyName, opt => opt.Ignore());
        }
    }

        return expression;
    }
}
Run Code Online (Sandbox Code Playgroud)

如何重写此扩展以与V5.x一起使用.我当然可以为每个属性添加以下内容.

.ForMember(dest => dest.LastUpdatedBy, opt => opt.Ignore())
Run Code Online (Sandbox Code Playgroud)

或不打电话

Mapper.AssertConfigurationIsValid();
Run Code Online (Sandbox Code Playgroud)

automapper automapper-5

8
推荐指数
1
解决办法
5168
查看次数

如果在Base DTO映射中配置了ExplicitExpansion,Automapper 5.2将忽略它

如果在基本数据传输对象的映射中配置了自动映射5.2(当前最新),则忽略ExplicitExpansion()配置.但是,如果直接在Derived DTO中配置了映射,它仍然可以正常工作.我有一对DTO类在字段集和映射配置中包含如此多的重复,我试图将它隔离到公共基础DTO类,但是这个问题阻止了我这样做.

下面的代码说明了这种奇怪的行为.有四个测试,其中两个失败,断言没有扩展基础DTO的属性.如果我将1-1..1-4行移动到2.1,则所有测试都通过.

我是否错过了一些代码或者这是Automapper中的错误,我必须向Automapper的错误跟踪器报告此问题?或者它可能是"按设计",但为什么呢?(Ivan Stoev提出了一个有效的解决方案,但请允许我推迟接受答案,因为我面临的问题不是那么简单,我在下面的更新中添加了更多细节).

UnitTest1.cs:

using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace AutoMapperIssue 
{
    public class Source { public string Name; public string Desc; }
    public class DtoBase              { public string Name { get; set; } }
    public class DtoDerived : DtoBase { public string Desc { get; set; } }
    [TestClass] public class UnitTest1
    {
        [AssemblyInitialize] public static void AssemblyInit(TestContext context)
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<Source, DtoBase>()
                    .ForMember(dto => dto.Name, conf => { …
Run Code Online (Sandbox Code Playgroud)

c# inheritance automapper automapper-5

8
推荐指数
1
解决办法
1105
查看次数

AutoMapper在验证期间抛出"无默认构造函数"

我有要映射的类,但它们没有默认的构造函数,我不希望它们有.这是因为我只映射到现有对象/从现有对象映射.

public class Order
{
    public string OrderName { get; set; }
    public Order(string name) 
    { 
        this.OrderName = name; 
    }
}

public class OrderProcessor
{
    private IService service;
    public string OrderName { get; set; }

    public OrderProcessor(IService service)
    { 
        this.service = service; 
        Mapper.Initialize(config => config.CreateMap<Order, OrderProcessor>());
    }

    public void Init()
    { 
        var order = this.service.GetOrder();

        // this works
        Mapper.Map(order, this);

        // this fails
        Mapper.Configuration.AssertConfigurationIsValid();
    }
}
Run Code Online (Sandbox Code Playgroud)

AutoMapper.AutoMapperConfigurationException:找到未映射的成员.查看下面的类型和成员.添加自定义映射表达式,忽略,添加自定义解析程序或修改源/目标类型对于无匹配的构造函数,添加无参数ctor,添加可选参数或映射所有构造函数参数

订单 - > OrderProcessor(目标成员列表)

没有可用的构造函数.

在Tests.cs中的Test():行

当我不想创建新对象时,如何使配置断言传递以及失败的原因?

.net c# automapper automapper-5

7
推荐指数
1
解决办法
5368
查看次数

使用开放泛型自动映射并在 ForMember 语句中包含源

我最近从 Automapper 4.2.1 升级到 5.1.1,并且在使用涉及开放泛型的先前有效映射时遇到问题。

以前,在 automapper 配置中,我有以下打开的通用映射配置

CreateMap(typeof(IPager<>), typeof(ModelPager<>))
    .ForMember("Items", e => e.MapFrom(o => (IEnumerable) o));
Run Code Online (Sandbox Code Playgroud)

这在 Automapper 4 中有效,但在InvalidOperaionException尝试通过IMapper.Map<TDestination>(source). 执行Items ForMember操作的映射时似乎失败,异常消息为“ Sequence contains no matching element

这反映在示例实现代码下面 IPager<TSource>器具IEnumerable<TSource>,以及Items财产ModelPager<TDestination>IEnumerable<TDestination>如此铸造应该是有效的。并且存在每个TSource到的有效映射TDestination

CreateMap<TSource, TDestination>();
Run Code Online (Sandbox Code Playgroud)

网页界面

public interface IPager<out TItem> : IEnumerable<TItem>
{
    int CurrentPage { get; }

    int PageCount { get; }

    int PageSize { get; }

    int TotalItems { get; } …
Run Code Online (Sandbox Code Playgroud)

generics automapper open-generics automapper-5

5
推荐指数
1
解决办法
1186
查看次数

向温莎城堡注册 AutoMapper 5.1.1

我正在尝试向 CastleWindsor 注册 AutoMapper 5.1.1,但我不知道在哪里正确调用 Mapper.Initialize()。

自动映射器简介:

namespace AutoMapper_DI.Mappings
{
    public class WebMappingProfile : Profile
    {        
        public WebMappingProfile()
        {
          CreateMap<Person, PersonDTO>();            
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

温莎城堡注册:

class MainInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {            
        container.AddFacility<TypedFactoryFacility>();

        container.Register(Component.For<IMapper>().UsingFactoryMethod(x =>
        {
            return new MapperConfiguration(c =>
            {
                c.AddProfile<WebMappingProfile>();
            }).CreateMapper();
        }));

        container.Register(Component.For<MainClass>());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后当我使用 _mapper 时,出现 Mapper 未初始化异常:

class MainClass
{
    private readonly IMapper _mapper;

    public MainClass(IMapper mapper)
    {
        _mapper = mapper;
    }

    public void Start()
    {            
        Person p = new …
Run Code Online (Sandbox Code Playgroud)

c# castle-windsor automapper-5

5
推荐指数
1
解决办法
2380
查看次数

使用 AutoMapper 对集合进行多态映射

TL;DR:我在使用多态映射时遇到了麻烦。我制作了一个带有测试套件的 github repo 来说明我的问题。请在这里找到它:链接到回购

我正在努力实现保存/加载功能。为了实现这一点,我需要确保我正在序列化的域模型以序列化友好的方式表示。为了实现这一点,我创建了一组 DTO,其中包含执行有意义的保存或加载所需的最低限度的信息集。

域的类似内容:

public interface IDomainType
{
  int Prop0 { get; set; }
}

public class DomainType1 : IDomainType
{
  public int Prop1 { get; set; }
  public int Prop0 { get; set; }
}

public class DomainType2 : IDomainType
{
  public int Prop2 { get; set; }
  public int Prop0 { get; set; }
}

public class DomainCollection
{
  public IEnumerable<IDomainType> Entries { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...对于 DTO

public interface IDto
{
  int …
Run Code Online (Sandbox Code Playgroud)

.net c# automapper automapper-5

5
推荐指数
1
解决办法
1566
查看次数

使用 Automapper 映射具有相似名称的成员

在我只能读取的远程数据库中,每天每小时有 24 列连续。他们的名字是 P1、P2、...、P24。

我必须将这些值复制到我自己的数据库中,我将其命名为 H1、H2、...、H24。

如何使用自动映射器将远程列映射到本地列?

CreateMap<Data.Context.SomeTableFromRemoteDb, Data.Entity.MyTableInLocaldb>()
                .ForMember(x => x.H1, y => y.MapFrom(z => z.P1))
                .ForMember(x => x.H2, y => y.MapFrom(z => z.P2))
                .ForMember(x => x.H3, y => y.MapFrom(z => z.P3))
                .ForMember(x => x.H4, y => y.MapFrom(z => z.P4))
                .ForMember(x => x.H5, y => y.MapFrom(z => z.P5))
                .ForMember(x => x.H6, y => y.MapFrom(z => z.P6))
                .ForMember(x => x.H7, y => y.MapFrom(z => z.P7))
                .ForMember(x => x.H8, y => y.MapFrom(z => z.P8))
                .ForMember(x => x.H9, y => y.MapFrom(z => …
Run Code Online (Sandbox Code Playgroud)

c# automapper automapper-5

5
推荐指数
1
解决办法
1771
查看次数