我在引导程序配置Automapper和我打电话Bootstrap()的 Application_Start(),我一直在说,这是错误的,因为我要修改我的Bootstrapper每一次我必须添加一个新的映射类,所以我违反了开闭原则.
你觉得怎么样,我真的违反了这个原则吗?
public static class Bootstrapper
{
public static void BootStrap()
{
ModelBinders.Binders.DefaultBinder = new MyModelBinder();
InputBuilder.BootStrap();
ConfigureAutoMapper();
}
public static void ConfigureAutoMapper()
{
Mapper.CreateMap<User, UserDisplay>()
.ForMember(o => o.UserRolesDescription,
opt => opt.ResolveUsing<RoleValueResolver>());
Mapper.CreateMap<Organisation, OrganisationDisplay>();
Mapper.CreateMap<Organisation, OrganisationOpenDisplay>();
Mapper.CreateMap<OrganisationAddress, OrganisationAddressDisplay>();
}
}
Run Code Online (Sandbox Code Playgroud) .net bootstrapping automapper open-closed-principle solid-principles
是否可以忽略根据源属性的值映射成员?
例如,如果我们有:
public class Car
{
public int Id { get; set; }
public string Code { get; set; }
}
public class CarViewModel
{
public int Id { get; set; }
public string Code { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找类似的东西
Mapper.CreateMap<CarViewModel, Car>()
.ForMember(dest => dest.Code,
opt => opt.Ignore().If(source => source.Id == 0))
Run Code Online (Sandbox Code Playgroud)
到目前为止,我唯一的解决方案是使用两个不同的视图模型,并为每个模型创建不同的映射.
奇怪的问题 - 我正在尝试使用AutoMapper 在枚举和字符串之间进行映射:
Mapper.CreateMap<MyEnum, string>()
.ForMember(dest => dest, opt => opt.MapFrom(src => src.ToString()));
Run Code Online (Sandbox Code Playgroud)
不要担心.ToString()我正在使用,实际上我在枚举本身上使用了一个扩展方法(.ToDescription()),但为了这个问题我一直保持简单.
当我只是简单地设置映射时,上面引发了一个对象引用错误.
考虑到这一点:
string enumString = MyEnum.MyEnumType.ToString();
Run Code Online (Sandbox Code Playgroud)
我看不出为什么我的AutoMapper配置没有.
AutoMapper可以处理这个,我做错了什么,或者这是AutoMapper的错误?
有任何想法吗?
编辑
我也尝试过使用自定义解析器:
Mapper.CreateMap<MyEnum, string>()
.ForMember(dest => dest, opt => opt.ResolveUsing<MyEnumResolver>());
public class MyEnumResolver: ValueResolver<MyEnum,string>
{
protected override string ResolveCore(MyEnum source)
{
return source.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
同一行上的错误相同.:(
我有以下型号:
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我希望能够使用AutoMapper Name将Tag类型的属性映射到我的一个viewmodel中的字符串属性.
我使用以下代码创建了一个自定义解析器来尝试处理此映射:
public class TagToStringResolver : ValueResolver<Tag, string>
{
protected override string ResolveCore(Tag source)
{
return source.Name ?? string.Empty;
}
}
Run Code Online (Sandbox Code Playgroud)
我使用以下代码进行映射:
Mapper.CreateMap<Tag, String>()
.ForMember(d => d, o => o.ResolveUsing<TagToStringResolver>());
Run Code Online (Sandbox Code Playgroud)
当我运行应用程序时,我收到错误:
仅对类型上的顶级单个成员支持成员的自定义配置.
我究竟做错了什么?
我希望能够使用automapper做这样的事情:
Mapper.CreateMap<Source, Destination>()
.ForMember<d => d.Member, "THIS STRING">();
Run Code Online (Sandbox Code Playgroud)
我希望d.Member始终是"这个字符串"而不是从源模型中的任何特定成员映射.将字符串字段放在源模型中并使用"THIS STRING"作为其值也不是一个选项.
AutoMapper是否以任何方式支持这些事情?
我在WCF服务中使用AutoMapper来返回User对象. User具有诸如AccountTeams本身具有子对象的属性.所有类都有AutoMapper贴图.
根据OperationContract所调用的WCF ,我想返回不同数量的数据.我希望一个OperationContract人返回该User对象而不AccountTeams填充其属性(及其子代),另一个OperationContract返回User整个属性链填充的对象.
有没有办法在同一个两个对象之间有两个不同的映射,或者我是否需要执行完整的映射以及null我不想从服务返回的属性?
我很难理解如何映射某些对象.请回答一些关于这个简单示例的问题.
示例代码
class User
{
private int id;
private string name;
}
class Group
{
private int id;
private string name;
private List<User> users;
}
[DataContract]
public class UserDto
{
[DataMember]
public int id { get; set; }
[DataMember]
public string name{ get; set; }
}
[DataContract]
public class GroupDto
{
[DataMember]
public int id { get; set; }
[DataMember]
public string name{ get; set; }
[DataMember]
public List<User> Users { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
地图集
Mapper.CreateMap<User, UserDto>();
Mapper.CreateMap<UserDto, User>(); …Run Code Online (Sandbox Code Playgroud) 我今天从AutoMapper 2.0.0更新到2.2.0,并意识到更新破坏了一些代码.想要在automapper github网站上发布问题之前在这里问一下这个问题.
我的一个目标类型初始化一个集合属性,如下所示:
public class PageOf<TModel>
{
public PageOf()
{
Items = Enumerable.Empty<TModel>();
}
public IEnumerable<TModel> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用automapper 2.0.0,这很好.当我更新到2.2.0时,映射到此目标类型会导致NotSupportedException,并显示消息"Collection is a fixed size".(该异常包含在AutoMapperMappingException中.)
我能够通过将上面的构造函数代码更改为此来解决此问题:
public PageOf()
{
Items = new List<TModel>();
}
Run Code Online (Sandbox Code Playgroud)
似乎AutoMapper 2.0.0正在丢弃Items属性中的任何值并使用setProperty访问器,而AutoMapper 2.2.0只是使用get属性访问器并尝试修改现有的IEnumerable.它看起来Enumerable.Empty<TModel>()只是替换一个零长度数组,这将解释异常.
这是一个错误吗?AutoMapper在2.0.0和2.2.0之间的变化会导致它忽略目标属性设置器,而是尝试修改现有的集合?
更新:
根据要求,这是CreateMap调用:
public class PagedQueryResultToPageOfItemsProfiler : Profile
{
protected override void Configure()
{
CreateMap<PagedQueryResult<EstablishmentView>, PageOfEstablishmentApiModel>();
}
}
Run Code Online (Sandbox Code Playgroud)
将PageOfEstablishmentApiModel类从继承PageOf<EstablishmentApiModel>.
这是Mapper.Map代码:
var query = Mapper.Map<EstablishmentViewsByKeyword>(input);
var results = _queryProcessor.Execute(query);
var …Run Code Online (Sandbox Code Playgroud) 我现在正在查找AutoMapper代码(为我正在研究的项目之一进行评估),坦率地说,我很惊讶:
Mapper类型),因此通常其任何方法都必须是线程安全的所有我能找到的都是这个问题,但即使是在那里做出的陈述似乎也是错误的:如果Map内部不使用线程安全的数据结构,那么它也不能被认为是线程安全的,如果我要去CreateMap在非并发上下文中调用,但同时使用Map.
即,例如ASP.NET MVC应用程序中AutoMapper唯一可能的使用模式是:
lock (mapperLock) {
... Mapper.AnyMethod(...) ...
}
Run Code Online (Sandbox Code Playgroud)
显然,如果我是对的,这是一个巨大的缺失.
所以我有两个问题:
我正在使用AutoMapper,正在映射的实体的一些值是我当前方法中的变量.我试过谷歌它但无济于事.我可以将一组KeyValue对或一个对象或东西传递给我的映射以使其使用这些值吗?
//comment variable is a Comment class instance
var imageComment = AutoMapper.Mapper.Map<Data.ImageComment>(comment);
//I want to pass in imageId so I dont have to manually add it after the mapping
imageComment.ImageId = imageId;
Run Code Online (Sandbox Code Playgroud) automapper ×10
c# ×7
.net ×4
automapper-2 ×3
wcf ×2
asp.net-mvc ×1
collections ×1
enums ×1
ienumerable ×1
mapping ×1
value-type ×1