AutoMapper 随机丢失映射信息
AutoMapper randomly lose mapping informations
我们有一个解决方案,WCF 服务使用 EF 6 从数据库获取数据。通过 IoC 容器注入存储库 DLL。在此 DLL 中,您可以找到实体、上下文、AutoMapper 配置文件等。
这是 SubscriberProfile 的示例:
public class SubscriberProfile : Profile
{
protected override void Configure()
{
MapDbToDto();
}
private static void MapDbToDto()
{
Mapper.CreateMap<SubscriberDb, SubscriberDto>()
.ForMember(x => x.FieldA, opt => opt.MapFrom(x => x.Filed123.Valeur))
.ForMember(x => x.Contact, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Contact)))
.ForMember(x => x.Conjoint, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Conjoint)));
Mapper.CreateMap<AnotherDb, AnotherDto>();
Mapper.CreateMap<ContactDb, ContactDto>();
}
}
以及添加配置文件的配置文件:
public static class AutoMapperRepositoryConfiguration
{
//Create mapings only once
public static void Configure()
{
if (Mapper.GetAllTypeMaps().Any())
return;
Mapper.Configuration.DisableConstructorMapping();
Mapper.AddProfile(new ConventionProfile());
Mapper.AddProfile(new SubscriberProfile());
Mapper.AddProfile(new BeneficiaryProfile());
}
}
并且在每个 repo 构造函数中调用 Configure 方法,因此它获取映射:
public SubscriberReadRepository(PlansContext context)
{
if (context == null)
throw new ArgumentNullException("context");
AutoMapperRepositoryConfiguration.Configure();
_context = context;
}
一切正常,几乎所有时间。在服务器上,有时不知从何而来,我们会收到臭名昭著的“缺少类型映射配置或不支持的映射”错误:
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Missing type map configuration or unsupported mapping.
Mapping types:
SubscriberDb -> SubscriberDto
MyRepo.SouscripteurDb -> MyRepo.SubscriberDto
Destination path:
SubscriberDto
Source value:
System.Data.Entity.DynamicProxies.SubscriberDb_0498438FE3D70326924850E4199183EC0EB2AC8DF509202F8CB4EF2D02D9E835 (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types:
SubscriberDb -> SubscriberDto
MyRepo.SouscripteurDb -> MyRepo.SouscripteurDto
Destination path:
SubscriberDto
Source value:
System.Data.Entity.DynamicProxies.SubscriberDb_0498438FE3D70326924850E4199183EC0EB2AC8DF509202F8CB4EF2D02D9E835
at MyRepo.SubscriberReadRepository.Get(Int32 idSouscripteur) in e:\BuildAgent\workdd90bc72a81e0e3\Sources\MyRepo\SubscriberReadRepository.cs:line 59
at MyRepo.SubscriberReadServices.Get(Int32 id) in e:\BuildAgent5\workdd90bc72a81e0e3\Sources\MyRepo\SubscriberReadServices.cs:line 33
at WCF.Services.SubscriberServices.Get(Int32 id) in e:\BuildAgen...).
一旦我们收到错误,none 的后续调用将起作用,但它们都会因相同的错误而崩溃。然后我们转到 IIS 并重新启动 WCF 服务,一切恢复正常。它可以毫无问题地工作几天,然后无缘无故地再次发生。我们的 DBA 确保没有对数据库进行任何修改。有人有想法吗?我在 Google 上到处检查,但找不到像我们这样随机的东西。我在这里看到了一个 post,其中 Jimmy Bogard 谈到在 "Mapper.CreateMap" 上调用 "base.CreateMap" 而不是,但还没有尝试过,因为我们甚至不知道为什么会出现这个错误。
您调用了错误的 CreateMap 方法。在您的配置文件中调用基本 CreateMap 方法 class:
public class SubscriberProfile : Profile
{
protected override void Configure()
{
MapDbToDto();
}
private static void MapDbToDto()
{
CreateMap<SubscriberDb, SubscriberDto>()
.ForMember(x => x.FieldA, opt => opt.MapFrom(x => x.Filed123.Valeur))
.ForMember(x => x.Contact, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Contact)))
.ForMember(x => x.Conjoint, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Conjoint)));
CreateMap<AnotherDb, AnotherDto>();
CreateMap<ContactDb, ContactDto>();
}
}
你的初始化会更好地使用 Initialize:
public static class AutoMapperRepositoryConfiguration
{
//Create mapings only once
public static void Configure()
{
if (Mapper.GetAllTypeMaps().Any())
return;
Mapper.Initialize(cfg => {
cfg.DisableConstructorMapping();
cfg.AddProfile(new ConventionProfile());
cfg.AddProfile(new SubscriberProfile());
cfg.AddProfile(new BeneficiaryProfile());
});
}
}
我们有一个解决方案,WCF 服务使用 EF 6 从数据库获取数据。通过 IoC 容器注入存储库 DLL。在此 DLL 中,您可以找到实体、上下文、AutoMapper 配置文件等。
这是 SubscriberProfile 的示例:
public class SubscriberProfile : Profile
{
protected override void Configure()
{
MapDbToDto();
}
private static void MapDbToDto()
{
Mapper.CreateMap<SubscriberDb, SubscriberDto>()
.ForMember(x => x.FieldA, opt => opt.MapFrom(x => x.Filed123.Valeur))
.ForMember(x => x.Contact, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Contact)))
.ForMember(x => x.Conjoint, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Conjoint)));
Mapper.CreateMap<AnotherDb, AnotherDto>();
Mapper.CreateMap<ContactDb, ContactDto>();
}
}
以及添加配置文件的配置文件:
public static class AutoMapperRepositoryConfiguration
{
//Create mapings only once
public static void Configure()
{
if (Mapper.GetAllTypeMaps().Any())
return;
Mapper.Configuration.DisableConstructorMapping();
Mapper.AddProfile(new ConventionProfile());
Mapper.AddProfile(new SubscriberProfile());
Mapper.AddProfile(new BeneficiaryProfile());
}
}
并且在每个 repo 构造函数中调用 Configure 方法,因此它获取映射:
public SubscriberReadRepository(PlansContext context)
{
if (context == null)
throw new ArgumentNullException("context");
AutoMapperRepositoryConfiguration.Configure();
_context = context;
}
一切正常,几乎所有时间。在服务器上,有时不知从何而来,我们会收到臭名昭著的“缺少类型映射配置或不支持的映射”错误:
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Missing type map configuration or unsupported mapping.
Mapping types:
SubscriberDb -> SubscriberDto
MyRepo.SouscripteurDb -> MyRepo.SubscriberDto
Destination path:
SubscriberDto
Source value:
System.Data.Entity.DynamicProxies.SubscriberDb_0498438FE3D70326924850E4199183EC0EB2AC8DF509202F8CB4EF2D02D9E835 (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types:
SubscriberDb -> SubscriberDto
MyRepo.SouscripteurDb -> MyRepo.SouscripteurDto
Destination path:
SubscriberDto
Source value:
System.Data.Entity.DynamicProxies.SubscriberDb_0498438FE3D70326924850E4199183EC0EB2AC8DF509202F8CB4EF2D02D9E835
at MyRepo.SubscriberReadRepository.Get(Int32 idSouscripteur) in e:\BuildAgent\workdd90bc72a81e0e3\Sources\MyRepo\SubscriberReadRepository.cs:line 59
at MyRepo.SubscriberReadServices.Get(Int32 id) in e:\BuildAgent5\workdd90bc72a81e0e3\Sources\MyRepo\SubscriberReadServices.cs:line 33
at WCF.Services.SubscriberServices.Get(Int32 id) in e:\BuildAgen...).
一旦我们收到错误,none 的后续调用将起作用,但它们都会因相同的错误而崩溃。然后我们转到 IIS 并重新启动 WCF 服务,一切恢复正常。它可以毫无问题地工作几天,然后无缘无故地再次发生。我们的 DBA 确保没有对数据库进行任何修改。有人有想法吗?我在 Google 上到处检查,但找不到像我们这样随机的东西。我在这里看到了一个 post,其中 Jimmy Bogard 谈到在 "Mapper.CreateMap" 上调用 "base.CreateMap" 而不是,但还没有尝试过,因为我们甚至不知道为什么会出现这个错误。
您调用了错误的 CreateMap 方法。在您的配置文件中调用基本 CreateMap 方法 class:
public class SubscriberProfile : Profile
{
protected override void Configure()
{
MapDbToDto();
}
private static void MapDbToDto()
{
CreateMap<SubscriberDb, SubscriberDto>()
.ForMember(x => x.FieldA, opt => opt.MapFrom(x => x.Filed123.Valeur))
.ForMember(x => x.Contact, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Contact)))
.ForMember(x => x.Conjoint, opt => opt.Condition(src => !Helpers.IsAllDefault(src.Conjoint)));
CreateMap<AnotherDb, AnotherDto>();
CreateMap<ContactDb, ContactDto>();
}
}
你的初始化会更好地使用 Initialize:
public static class AutoMapperRepositoryConfiguration
{
//Create mapings only once
public static void Configure()
{
if (Mapper.GetAllTypeMaps().Any())
return;
Mapper.Initialize(cfg => {
cfg.DisableConstructorMapping();
cfg.AddProfile(new ConventionProfile());
cfg.AddProfile(new SubscriberProfile());
cfg.AddProfile(new BeneficiaryProfile());
});
}
}