我确定我错过了一些简单的事情。首先,我将显示我编写的用于连接管道的所有代码,然后我将显示异常消息。然后,我将阐述我试图解决的问题。
LicenceTrackerProfile
public class LicenceTrackerProfile : Profile
{
const string LicenceTrackerProfileName = "LicenceTrackerProfile";
public override string ProfileName
{
get { return LicenceTrackerProfileName; }
}
protected override void Configure()
{
// initialize mappings here
new ViewModelMappings(this).Initialize();
}
}
MapperBootstrapper
public class MapperBootstrapper
{
public void Configure()
{
var profile = new LicenceTrackerProfile();
AutoMapper.Mapper.Initialize(p => p.AddProfile(profile));
}
}
MappingBase
public abstract class MappingBase
{
private readonly Profile _profile;
protected MappingBase(Profile profile)
{
_profile = profile;
_profile.SourceMemberNamingConvention = new PascalCaseNamingConvention();
_profile.DestinationMemberNamingConvention = new PascalCaseNamingConvention();
}
public Profile Profile
{
get { return _profile; }
}
}
UniversalMapper
public class UniversalMapper : IUniversalMapper
{
private readonly IMappingEngine _mappingEngine;
public UniversalMapper(IMappingEngine mappingEngine)
{
_mappingEngine = mappingEngine;
}
public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
{
return _mappingEngine.Map(source, destination);
}
}
ViewModelMappings
public class ViewModelMappings : MappingBase, IMappingInitializer
{
private readonly Profile _profile;
public ViewModelMappings(Profile profile) : base(profile)
{
_profile = profile;
_profile.SourceMemberNamingConvention = new PascalCaseNamingConvention();
_profile.DestinationMemberNamingConvention = new PascalCaseNamingConvention();
}
public void Initialize()
{
// data to domain mappings
Profile.CreateMap<EFDTO.Enums.FileTypes, Domain.FileTypes>();
Profile.CreateMap<EFDTO.Licence, Domain.Licence>();
Profile.CreateMap<EFDTO.LicenceAllocation, Domain.LicenceAllocation>();
Profile.CreateMap<EFDTO.Person, Domain.Person>();
Profile.CreateMap<EFDTO.Software, Domain.Software>();
Profile.CreateMap<EFDTO.SoftwareFile, Domain.SoftwareFile>();
Profile.CreateMap<EFDTO.SoftwareType, Domain.SoftwareType>();
}
}
注意,正在调用initialize方法和Configure方法,因此它们不会被错过&#34;
异常
缺少类型映射配置或不支持的映射。
映射类型:软件 - &gt;软件LicenceTracker.Entities.Software - &GT; LicenceTracker.DomainEntities.Software
目标路径:软件
来源价值:LicenceTracker.Entities.Software
疑难解答 忽略列。我打算忽略列,从所有列开始,然后通过逐个忽略它们来消除它们,直到找到问题列。但是,令我惊讶的是,当我忽略所有列时会发生错误:
Profile.CreateMap<EFDTO.Software, Domain.Software>()
.ForMember(software => software.Licences, e => e.Ignore())
.ForMember(software => software.Name, e => e.Ignore())
.ForMember(software => software.SoftwareFiles, e => e.Ignore())
.ForMember(software => software.Type, e => e.Ignore())
.ForMember(software => software.Description, e => e.Ignore())
.ForMember(software => software.Id, e => e.Ignore())
.ForMember(software => software.TypeId, e => e.Ignore()
.ForMember(software => software.ObjectState, e => e.Ignore());
Domain实体具有[DataContract](在类级别)和[DataMember](在方法级别)属性。我也将这些属性添加到EF实体中。
除此之外,我没有想法。这一切似乎都正确连线。
我错过了什么?
答案 0 :(得分:0)
我回过头来英勇回答我的问题。
问题出在Service中,它创建了UniversalMapper对象(原谅邋code的代码,它还不是最终的):
public class LicenceTrackerService : ILicenceTrackerService, IDisposable
{
LicenceTrackerContext context = new LicenceTrackerContext();
private MapperBootstrapper mapperBootstrapper;
private IUniversalMapper mapper = new UniversalMapper(Mapper.Engine);
private IUnitOfWork unitOfWork;
public LicenceTrackerService()
{
unitOfWork = new UnitOfWork(context, new RepositoryProvider(new RepositoryFactories()));
mapperBootstrapper = new MapperBootstrapper();
mapperBootstrapper.Configure();
Database.SetInitializer(new LicenceTrackerInitializer());
context.Database.Initialize(true);
}
public int GetNumber()
{
return 42;
}
public List<LicenceTracker.DomainEntities.Software> GetSoftwareProducts()
{
var productsRepo = unitOfWork.Repository<Software>();
var list = productsRepo.Query().Select().ToList();
var softwareList = new List<LicenceTracker.DomainEntities.Software>();
foreach (var software in list)
{
var softwareProduct = new LicenceTracker.DomainEntities.Software();
softwareList.Add(Mapper.Map(software, softwareProduct));
}
return softwareList;
}
public void Dispose()
{
unitOfWork.Dispose();
}
}
我仍然不确定原因,但是在构造函数之外初始化映射器(默认值样式)并不高兴。通过将该实例化移动到服务的构造函数中,它起作用了:
private IUniversalMapper mapper;
public LicenceTrackerService()
{
mapper = new UniversalMapper(Mapper.Engine);
...
}
显然有一些关于静态属性(Mapper.Engine)和我不理解的默认实例。
无论如何,因为我计划将UniversalMapper注入服务中,所以没什么大不了的。
修改强> 我现在实际上已经找到了问题。这是订购的事情。使用Automapper,我必须在将Mapper.Engine插入UniversalMapper之前使用Profile初始化映射器。
显然,Mapper.Engine属性的 Get 方面不仅仅是对象的内存引用。是的,快速浏览一下Automapper中的代码即可确认。
因此,将Get属性的结果分配给 UniversalMapper 的 _mappingEngine 字段必须在配置该引擎后发生。