我正在尝试在Entity Framework IQueryables上使用Automapper投影.
在应用程序启动时,我创建并添加了所有映射配置文件,这些配置文件使用非静态CreateMap方法创建映射.
所有这些配置文件都在我的IoC容器中注册.
虽然我在mappingConfiguration的实例中看到了映射配置文件,但我得到了缺少的映射异常.
可能是什么问题呢?我错过了什么吗?我正在使用Automapper 4.2.1
我注意到在添加静态Mapper.CreateMap时,它工作正常.预测只适用于静态API吗?我想避免使用静态API.
完整代码:
public class ItemEntityToItemView : Profile
{
public override void Configure()
{
CreateMap<ItemEntity, ItemView>();
// Without this line, I get missing Map type configuration.
Mapper.CreateMap<ItemEntity, ItemView>();
}
}
public interface IEntitiesProjector
{
IQueryable<T> SelectTo<T>(IQueryable source);
}
public class EntitiesProjector : IEntitiesProjector
{
private readonly IMapperConfiguration _mapperConfig;
public EntitiesProject(IMapperConfiguration mapperConfig)
{
_mapperConfig = mapperConfig;
}
public IQueryable<T> SelectTo<T>(IQueryable source)
{
return source.ProjectTo<T>(_mapperConfig);
}
}
public class ItemsRepository : IITemsRepository
{
public IQueryable<ItemEntity> …Run Code Online (Sandbox Code Playgroud) c# entity-framework automapper entity-framework-6 automapper-4
我正在努力在我们的服务中实现AutoMapper,并且在我们的单元测试中看到了一个非常令人困惑的问题.
首先,此问题涉及以下对象及其各自的映射:
public class DbAccount : ActiveRecordBase<DbAccount>
{
// this is the ORM entity
}
public class Account
{
// this is the primary full valued Dto
}
public class LazyAccount : Account
{
// this class as it is named doesn't load the majority of the properties of account
}
Mapper.CreateMap<DbAccount,Account>();
//There are lots of custom mappings, but I don't believe they are relevant
Mapper.CreateMap<DbAccount,LazyAccount>();
//All non matched properties are ignored
Run Code Online (Sandbox Code Playgroud)
它也涉及这些对象,但此时我还没有使用AutoMapper映射这些对象:
public class DbParty : ActiveRecordBase<DbParty>
{
public …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 AutoMapper 合并来自多个对象的数据,但遇到了一些似乎无法解决的问题。
我有一个对象,如:
public class Parent
{
public string Id { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public string Key { get; set; }
public int? Value1 { get; set; }
public int? Value2 { get; set; }
public int? Value3 { get; set; }
public int? Value4 { get; set; }
public int? Value5 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
显然子属性并不都是整数,但大多数都是可以为空的。
我在应用程序的两个不同层中有这些对象,因此我使用 AutoMapper 在它们之间进行转换:
{
Mapper.CreateMap<Parent, ParentDTO>();
Mapper.CreateMap<ParentDTO, Parent>();
Mapper.CreateMap<Child, …Run Code Online (Sandbox Code Playgroud) 我在解决如何获取Automapper 4.2.1以允许类型映射时遇到一些问题,其中目标值可能为空,具体取决于源值。
旧版本的 Automapper 允许通过 Mapper 配置设置AllowNullDestination标志,但我找不到新版本的等效配方,并且通过静态 Mapper 对象进行配置的旧机制似乎已过时。
我尝试了以下方法但没有成功:
这是一个演示该问题的简单测试用例。由于 Substitute 方法返回 null,因此在最后一行失败并出现 AutoMapperMappingException 。我希望这两个映射都能成功。
我宁愿避免在解决方案中使用.ForMember,因为在我试图解决的实际场景中,bool 和“object”(实际上是自定义类)之间的映射应该应用于整个对象树。
尽管 StackOverflow 上有几个类似的问题,但我还没有找到涉及 Automapper 最新版本的问题。
在此先感谢您的任何建议
using AutoMapper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace AutoMapperTest
{
[TestClass]
public class ExampleTest
{
[TestMethod]
public void NullDestinationCanBeMapped()
{
var mapper = new MapperConfiguration(configuration =>
{
configuration.CreateMap<Source, Target>();
//How should the following mapping be modified to pass the test?
configuration.CreateMap<bool, object>()
.Substitute(i => i …Run Code Online (Sandbox Code Playgroud) 在我的Web API控制器方法中,在映射UpdatePlaceDTO到之前PlaceMaster,我进行数据库调用以填充Map未涵盖的属性,但由于某种原因,AutoMapper使这些属性为null.
var mappedPlaceMaster = _mapper.Map<PlaceMaster>(placeMasterDTO);
// mappedPlaceMaster.EntityId is null
Run Code Online (Sandbox Code Playgroud)
我已经尝试过IgnoreExistingMembers的许多解决方案,但它们都不起作用.
这就是我所拥有的
public class PlaceMapperProfile : Profile
{
protected override void Configure()
{
// TO DO: This Mapping doesnt work. Need to ignore other properties
//CreateMap<UpdatePlaceDto, PlaceMaster>()
// .ForMember(d => d.Name, o => o.MapFrom(s => s.Name))
// .ForMember(d => d.Description, o => o.MapFrom(s => s.Description))
// .ForMember(d => d.ParentPlaceId, o => o.MapFrom(s => s.ParentPlaceId))
// .ForMember(d => d.LeftBower, o => o.MapFrom(s => s.LeftBower))
// .ForMember(d => …Run Code Online (Sandbox Code Playgroud) 我有两个列表,SRCList 和 DESTList。
SRCList 对象有 6 条记录。
我正在使用 automapper 来映射这两个列表。
映射时,automapper 在映射 6 条记录中的第 4 条记录时遇到任何问题,我得到 AutoMapperMappingException。
我可以跳过导致错误的记录的映射并继续映射其他记录吗?因此,在上面的示例中, DESTList 将有 5 条记录,跳过第 4 条记录。
我尝试过各种各样的排列,但我目前的配置(因为它与AutoMapper有关)是这样的:
builder.RegisterAssemblyTypes().AssignableTo(typeof(Profile)).As<Profile>();
builder.Register(c => new MapperConfiguration(cfg =>
{
foreach (var profile in c.Resolve<IEnumerable<Profile>>())
{
cfg.AddProfile(profile);
}
})).AsSelf().SingleInstance();
builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve)).As<IMapper>().InstancePerLifetimeScope();
builder.RegisterType<MappingEngine>().As<IMappingEngine>();
Run Code Online (Sandbox Code Playgroud)
我有一个构造函数使用IMapper mapper,但我继续得到YSOD:
None of the constructors found with'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'
on type '' can be invoked with the available services and parameters:
Cannot resolve parameter 'AutoMapper.IMapper mapper' of constructor
'Void .ctor(...,...,..., AutoMapper.IMapper)'.
Run Code Online (Sandbox Code Playgroud)
这个类在没有automapper引用的情况下工作得很好,所以我确定麻烦在于我的automapper配置.
我不确定我在这里缺少什么,因为我对AutoFac和AutoMapper都很新.
编辑:
我也尝试过:
builder.Register(c => new MapperConfiguration(cfg =>
{
cfg.CreateMap<IdentityUser, AspNetUser>().ReverseMap();
})).AsSelf().SingleInstance();
builder.Register(ctx => ctx.Resolve<MapperConfiguration>().CreateMapper()).As<IMapper>();
//I've tried both of these lines separately, neither work
builder.Register(c => …Run Code Online (Sandbox Code Playgroud) 我们使用 Automapper 一段时间了,我们认为它非常实用,感谢您创建它!
然而,我们有一个问题:
问题
“如何配置 AutoMapper 将源属性映射到内部目标属性?”
背景
在我们的分层架构中,Dto对象永远不会离开数据访问层,只有Domain对象被允许进出数据访问层。因此,从域 POV 来看,域对象不应包含任何数据库知识。然而,实际上数据库 ID 非常有用,随身携带 - 希望“业务层”开发人员不应该知道它们。
解决方案:将数据库 ID 添加到域对象,但将它们作为内部营销,这样它们就不会暴露给“业务层”。接下来将公共层(拥有域对象)内部结构公开给数据访问层。问题解决了。预计我们无法弄清楚如何让 Automapper (> v3.3.0) 使用我们的内部属性。
3.3.0版本BindingFlags被曝光,用于解决该问题。
例子
通用DLL
public class Person
{
public Parent Father { get; set; }
internal int FatherId {get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
数据访问.dll
internal class PersonDto
{
public ParentDto Father { get; set; }
public int FatherId {get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
在我们的 Profile 类中,我们有CreateMap<PersonDto, Person>();
编辑 1 - 修复了 Father 返回类型中的拼写错误。
编辑 2 …
在我的项目类库(dll)中如何使用automapper苦苦挣扎.请参阅下面我的整体解决方案的结构.
WebApp启动,在Global.asax App Start中,调用AutoMapper.Configure()方法以添加映射配置文件.现在我只是添加Services.AutoMapperViewModelProfile.但我需要以某种方式说明每个WebStoreAdapters中的配置文件(下例中的BigCommerce和Shopify).我希望不要在WebApp中添加对每个WebStoreAdapter的引用,只是为了能够在AutoMapperConfig中添加配置文件.如果我在WebStoreFactory中添加对AutoMapper.Initialize的另一个调用,它将覆盖WebApp中的一个.
还有另一种方式,我错过了或完全偏离这里以其他方式?
WebApp
- AutoMapperConfig
- AddProfile Services.AutoMapperViewModelProfile
Services.dll
- AutoMapperViewModelProfile
Scheduler.dll (uses HangFire to execute cron jobs to get data from shop carts. Its UI is accessed via the WebApp)
WebStoreAdapter.dll
-WebStoreFactory
BigCommerceAdapter.dll
- AutoMapperBigCommerceDTOProfile
ShopifyAdapter.dll
- AutoMapperShopifyDTOProfile
Run Code Online (Sandbox Code Playgroud)
从Global.asax调用初始化:
public static class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(am =>
{
am.AddProfile<AutoMapperViewModelProfile>();
});
}
}
Run Code Online (Sandbox Code Playgroud)
轮廓:
public class AutoMapperViewModelProfile : Profile
{
public override string ProfileName
{
get { return this.GetType().ToString(); }
}
protected override …Run Code Online (Sandbox Code Playgroud) 如何获取目标属性的名称:
Public class Source{
public string FirstName{ get; set; }
}
public class Destination{
public string C_First_Name{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用AutoMapper,当我传递源属性Name时,如何获取目标属性的名称.
我无法想象如何将以下结构图实现转换为统一.
public AutoMapperRegistry()
{
var profiles =
from t in typeof (AutoMapperRegistry).Assembly.GetTypes()
where typeof (Profile).IsAssignableFrom(t)
select (Profile)Activator.CreateInstance(t);
var config = new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
});
For<MapperConfiguration>().Use(config);
For<IMapper>().Use(ctx => ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance));
}
Run Code Online (Sandbox Code Playgroud) Mapper.DynamicMap(object, source, destination) 在最新版本的 Automapper 中已弃用。
当源值和目标值直到运行时才知道时,此方法的替代方法是什么?