我正在使用ViewModelBuilder类将我的模型映射到ViewModels。
问题是,当我尝试为Projects属性构建视图模型时,我也使用了viewmodelbuilder,而viewmodelbuilder的模型有一个返回Account的引用,它也将尝试映射到viewmodel。结果是stackoverflowexeption。
如何解决这个问题? 我想过将一个bool发送给映射函数,但是后来我将丢失一些我做要映射的嵌套属性的映射。
非常感谢我能得到的任何建议!
public class AccountViewModelBuilder : IViewModelBuilder<AccountViewModel, Account>
{
protected AllViewModelBuilders _allViewModelBuilders { get; private set; }
public AccountViewModelBuilder(AllViewModelBuilders allViewModelBuilders)
{
_allViewModelBuilders = allViewModelBuilders;
}
public AccountViewModel BuildFromEntity(Account entity)
{
return new AccountViewModel()
{
ID = entity.ID,
Name = entity.Name,
//Projects = _allViewModelBuilders.ProjectViewModelBuilder.BuildFromEntity(entity.Projects).ToList()
};
}
public Account BuildFromViewModel(AccountViewModel viewModel, Account entity)
{
if (entity == null) return null;
entity.Name = viewModel.Name;
//entity.Projects = _allViewModelBuilders.ProjectViewModelBuilder.BuildFromViewModel(viewModel.Projects).ToList();
return entity;
}
public IEnumerable<AccountViewModel> BuildFromEntity(ICollection<Account> entities)
{
foreach (var entity in entities)
yield return BuildFromEntity(entity);
}
public IEnumerable<Account> BuildFromViewModel(ICollection<AccountViewModel> viewModels)
{
throw new NotImplementedException();
}
}
修改 所以我决定使用AutoMapper,带有一些扩展......
public static class ConditionExtensions
{
public static void IgnoreIfSourceIsNull<T>(this IMemberConfigurationExpression<T> expression)
{
expression.Condition(IgnoreIfSourceIsNull);
}
static bool IgnoreIfSourceIsNull(ResolutionContext context)
{
if (!context.IsSourceValueNull)
{
return true;
}
var result = context.GetContextPropertyMap().ResolveValue(context.Parent);
return result.Value != null;
}
}
public static class AutoMapperConfig
{
public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof(TSource);
var destinationType = typeof(TDestination);
var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType)
&& x.DestinationType.Equals(destinationType));
foreach (var property in existingMaps.GetUnmappedPropertyNames())
{
expression.ForMember(property, opt => opt.Ignore());
}
return expression;
}
public static void Configure()
{
Mapper.CreateMap<Project, ProjectViewModel>().IgnoreAllNonExisting();
Mapper.CreateMap<ProjectViewModel, Project>().IgnoreAllNonExisting().ForAllMembers(c => c.IgnoreIfSourceIsNull());
Mapper.CreateMap<LogbookUser, RegisterViewModel>().IgnoreAllNonExisting();
Mapper.CreateMap<RegisterViewModel, LogbookUser>().IgnoreAllNonExisting().ForAllMembers(c => c.IgnoreIfSourceIsNull());
Mapper.CreateMap<Account, AccountViewModel>().IgnoreAllNonExisting();
Mapper.CreateMap<AccountViewModel, Account>().IgnoreAllNonExisting().ForAllMembers(c => c.IgnoreIfSourceIsNull());
Mapper.CreateMap<FileGroup, FileGroupViewModel>().IgnoreAllNonExisting();
Mapper.CreateMap<FileGroupViewModel, FileGroup>().IgnoreAllNonExisting().ForAllMembers(c => c.IgnoreIfSourceIsNull());
Mapper.CreateMap<AttachedFile, AttachedFileViewModel>().IgnoreAllNonExisting();
Mapper.CreateMap<AttachedFileViewModel, AttachedFile>().IgnoreAllNonExisting().ForAllMembers(c => c.IgnoreIfSourceIsNull());
Mapper.CreateMap<Customer, CustomerViewModel>().IgnoreAllNonExisting();
Mapper.CreateMap<CustomerViewModel, Customer>().IgnoreAllNonExisting().ForAllMembers(c => c.IgnoreIfSourceIsNull());
Mapper.CreateMap<WorkOrder, WorkOrderViewModel>().IgnoreAllNonExisting();
Mapper.CreateMap<WorkOrderViewModel, WorkOrder>().IgnoreAllNonExisting().ForAllMembers(c => c.IgnoreIfSourceIsNull());
}
}