为什么我需要创建相同的地图,如果它已经在Automapper中创建
本文关键字:创建 如果 Automapper 地图 为什么 | 更新日期: 2023-09-27 18:17:33
我使用的是Automapper 4.1.1,因为。net Framework 4.0需要。我决定在每个应用程序启动时调用Automapper配置。所以,我的类看起来像:
// AutoMapper Business Logic Layer Configuration
public class PersonProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Person, PersonDTO>().ReverseMap();
}
}
public class PhotoProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Photo, PhotoDTO>().ReverseMap();
}
}
public class DicProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Dic, DicDTO>().ReverseMap();
}
}
public class SubjectProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Subject, SubjectDTO>().ReverseMap();
}
}
public class PhotoSubjectIgnoreProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Person, PersonDTO>()
.ForMember(ph => ph.Photos, opt => opt.Ignore())
.ForMember(sub => sub.Subjects, opt => opt.Ignore());
}
}
public class PhotoSubjectIncludeProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Person, PersonDTO>()
.ForMember(pe => pe.Photos, opt => opt.MapFrom(p => p.Photos))
.ForMember(dto => dto.Subjects, opt => opt.MapFrom(p => p.Subjects));
}
}
// AutoMapper Presentation Layer Configuration
public class PersonViewProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<PersonDTO, PersonViewModel>()
.ForMember(model => model.Photos, opt => opt.MapFrom(dto => dto.Photos))
.ForMember(model => model.Subjects, opt => opt.MapFrom(dto => dto.Subjects))
.ForMember(model => model.BirthdaySingle, opt => opt.MapFrom(dto => dto.BirthdaySingle.NullIntToNullDateTime("yyyyMMdd")));
Mapper.CreateMap<PersonViewModel, PersonDTO>()
.ForMember(dto => dto.Photos, opt => opt.MapFrom(model => model.Photos))
.ForMember(dto => dto.Subjects, opt => opt.MapFrom(dto => dto.Subjects))
.ForMember(dto => dto.BirthdaySingle, opt => opt.MapFrom(model => model.BirthdaySingle.NullDateTimeToNullInt("yyyyMMdd")));
}
}
public class PersonShortViewProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<PersonDTO, PersonListViewModel.PersonShortViewModel>()
.IgnoreAllNonExisting().ForMember(model => model.Birthday,opt => opt.MapFrom(dto => dto.BirthdaySingle.NullIntToNullDateTime("yyyyMMdd")));
}
}
public class PhotoViewProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<PhotoDTO, PhotoViewModel>().ReverseMap();
}
}
public class DicViewProfile:Profile
{
protected override void Configure()
{
Mapper.CreateMap<DicDTO, DicViewModel>().ForSourceMember(dto => dto.Id, opt => opt.Ignore());
Mapper.CreateMap<DicViewModel, DicDTO>().ForMember(dto => dto.Id, opt => opt.Ignore());
}
}
public class SubjectViewProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<SubjectDTO, SubjectViewModel>().ForSourceMember(dto => dto.Id, opt => opt.Ignore());
Mapper.CreateMap<SubjectViewModel, SubjectDTO>().ForMember(dto => dto.Id, opt => opt.Ignore());
}
}
收集整个应用程序中的配置文件的类:
public static class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(configuration =>
GetConfiguration(Mapper.Configuration)
);
Mapper.AssertConfigurationIsValid();
}
private static void GetConfiguration(IConfiguration configuration)
{
// Interesting thing: we need to use order by because we need photo mapping to be before Person mappings
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var allTypes = assemblies.SelectMany(assembly => assembly.GetExportedTypes());
var profiles = allTypes.Where(type => typeof(Profile).IsAssignableFrom(type) && !type.IsAbstract && type.IsSubclassOf(typeof(Profile))).ToArray();
foreach (var profile in profiles)
{
configuration.AddProfile(Activator.CreateInstance(profile) as Profile);
}
}
}
在Program.cs
类中调用main函数:
internal static class Program
{
/// <summary>
/// Главная точка входа для приложения.
/// </summary>
[STAThread]
private static void Main()
{
AutoMapperConfiguration.Configure();
// ...
}
}
我有一个方法:
/// <summary>
/// Get elements of type PersonDTO using paging settings
/// </summary>
/// <param name="pageNumber">Page number to get</param>
/// <param name="pageSize">Rows per page</param>
/// <returns></returns>
public IQueryable<PersonDTO> GetPersons(int pageNumber, int pageSize)
{
if (pageNumber < 1)
{
throw new ValidationException("Початкове значення має бути більше 0.", "");
}
if (pageSize < 1)
{
throw new ValidationException("Кількість записів має бути більше 0.", "");
}
PageInfo.TotalItems = Database.Persons.CountAll();
PageInfo.CurrentPage = pageNumber;
PageInfo.PageSize = pageSize;
// применяем автомаппер для проекции одной коллекции на другую
/*Mapper.CreateMap<Person, PersonDTO>()
.ForMember(ph => ph.Photos, opt => opt.Ignore())
.ForMember(sub => sub.Subjects, opt => opt.Ignore());*/
return Database.Persons.GetAll((pageNumber - 1) * pageSize, pageSize).ProjectTo<PersonDTO>();
}
我得到这个错误:
Message:
Value cannot be null.
Parameter name: source
ParamName:
source
Source:
System.Core
StackTrace:
at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
at lambda_method(Closure , Person )
at System.Linq.Enumerable.<>c__DisplayClass7_0`3.<CombineSelectors>b__0(TSource x)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Windows.Forms.BindingSource.GetListFromEnumerable(IEnumerable enumerable)
at System.Windows.Forms.BindingSource.ResetList()
at System.Windows.Forms.BindingSource.set_DataSource(Object value)
at Reestr.WinForms.Views.FrmMain.BindGrid(Int32 pageIndex, Expression`1 predicate) in B:'Programming'Visual Studio 2012'Projects'Reestr_2'Reestr.WinForms'Views'FrmMain.cs:line 270
TargetSite:
{System.Collections.Generic.IEnumerable`1[TResult] Select[TSource,TResult](System.Collections.Generic.IEnumerable`1[TSource], System.Func`2[TSource,TResult])}
InnerException: null
但是!如果我取消注释Mapper.CreateMap
行,这个错误消失,一切工作正常。不明白为什么会这样,因为我已经在PhotoSubjectIgnoreProfile
类中创建了这个地图。方法:
public PersonDTO GetPerson(long id)
{
var person = Database.Persons.GetById(id);
if (person == null)
{
throw new ValidationException("Об'єкт не знайдено.", "");
}
// применяем автомаппер для проекции Person на PersonDTO
/*Mapper.CreateMap<Person, PersonDTO>()
.ForMember(pe => pe.Photos, opt => opt.MapFrom(p => p.Photos))
.ForMember(pe => pe.Subjects, opt => opt.MapFrom(p => p.Subjects));*/
return Mapper.Map<PersonDTO>(person);
}
这个地图也已经创建在PhotoSubjectIncludeProfile
类…我该如何解决这个问题?谢谢你!
您的所有配置文件都不正确。你需要在Profile上调用CreateMap,而不是Mapper。CreateMap:
public class PersonProfile : Profile
{
protected override void Configure()
{
CreateMap<Person, PersonDTO>().ReverseMap();
}
}