[英]Mapping class array using AutoMapper
我是AutoMapper的新手,并尝试映射Array
类ItemLink[]
。
public class ViewModel
{
public ItemLink[] ItemLinks { get; set; }
}
public class ItemLink
{
public string Description { get; set; }
}
我试过了:
Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
错误:
“映射器未初始化。使用适当的配置调用Initialize。如果您试图通过容器或其他方式使用Mapper实例,请确保您没有对静态Mapper.Map方法的任何调用,并且如果您使用的是ProjectTo或UseAsDataSource扩展方法,请确保您传入适当的IConfigurationProvider实例。”
难道不是简单的映射?
编辑1
为了进一步说明,我从数据库中获得了类似的类结构。 例,
public class Db
{
public ItemLink[] ItemLinks { get; set; }
}
因此,我想将ViewModel.ItemLink[]
与Db.ItemLink[]
映射。
您不能像在Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
那样为通用参数提供变量Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
。 它称为Type参数,并且必须是类型。
正如@gisek在他的回答中提到的,您需要首先配置映射器。 通常,它是在应用程序启动时完成的。
您可以考虑从db获取完整的对象,但是您也可以选择使用Queryable Extensions,那里的可查询扩展仅用于获取视图模型所需的数据。
配置。 我假设您具有DB
中实体的名称空间DB
,以及视图模型的View
命名空间。
Mapper.Initialize(cfg => {
cfg.CreateMap<DB.ItemLink, View.ItemLink>();
});
Mapper.Configuration.AssertConfigurationIsValid();
从数据库获取完整实体 ,然后将其映射到属性:
var viewModel = new View.Item();
viewModel.ItemLinks = Mapper.Map<View.ItemLink[]>(db.ItemLinks.ToArray());
从数据库查看模型的项目实体 :
var viewModel = new View.Item();
viewModel.ItemLinks = db.ItemLinks.ProjectTo<View.ItemLink>().ToArray();
我以为你正在使用.net mvc
首先,您需要在Application Start上初始化映射,而无需每次都在控制器中进行初始化等。
出现以下错误意味着您没有初始化映射器,自动映射器不知道您的源对象和目标对象。
错误:
“映射器未初始化。使用适当的配置调用Initialize。如果您试图通过容器或其他方式使用Mapper实例,请确保您没有对静态Mapper.Map方法的任何调用,并且如果您使用的是ProjectTo或UseAsDataSource扩展方法,请确保您传入适当的IConfigurationProvider实例。”
解决方案:
在您的App_Start文件夹中创建一个AutoMapperConfig对象。
public class AutoMapperConfig
{
public static void Register()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<source,destination>(); /*If source and destination object have same propery */
cfg.CreateMap<source, destination>()
.ForMember(dest => dest.dId, opt => opt.MapFrom(src => src.sId)); /*If source and destination object haven't same property, you need do define which property refers to source property */
});
}
}
在您的Global.asax.cs中
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutoMapperConfig.Register(); // Call Register method on App_Start
}
在您的控制器中
var mappedArray = Mapper.Map<viewmodel.ItemLink[]>(db.ItemLinks);
要么
var mappedArray = Mapper.Map<viewmodel.ItemLink[],ItemLinks[]>(db.ItemLinks); //ItemLinks[] refers to your dto.
您需要先配置映射器。
有两种可能的方法,静态和非静态。 我倾向于非静态,因为它允许您创建多个映射器,这些映射器可以使用不同的映射策略。
非静态示例:
using AutoMapper;
namespace Experiments
{
class Program
{
static void Main(string[] args)
{
var links = new ItemLink[]
{
new ItemLink {Description = "desc 1"},
new ItemLink {Description = "desc 2"},
};
var item = new Item
{
ItemLinks = links,
};
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ItemLink, ItemLink>(); // you can extend this part of the configuration here
cfg.CreateMap<Item, Item>();
cfg.CreateMap<ItemLink, MyCustomClass>()
.ForMember(myCustomClass => myCustomClass.DescriptionWithDifferentName,
expression => expression.MapFrom(itemLink => itemLink.Description)); // to map to a different type
// more configs can do here
// e.g. cfg.CreateMap<Item, SomeOtherClass>();
});
IMapper mapper = new Mapper(config);
ItemLink linkClone = mapper.Map<ItemLink>(links[0]);
ItemLink[] linkArrayClone = mapper.Map<ItemLink[]>(item.ItemLinks);
Item itemClone = mapper.Map<Item>(item);
MyCustomClass myCustomClassObject = mapper.Map<MyCustomClass>(links[0]);
}
}
public class Item
{
public ItemLink[] ItemLinks { get; set; }
}
public class ItemLink
{
public string Description { get; set; }
}
public class MyCustomClass
{
public string DescriptionWithDifferentName { get; set; }
}
}
静态示例:
using AutoMapper;
namespace Experiments
{
class Program
{
static void Main(string[] args)
{
var links = new ItemLink[]
{
new ItemLink {Description = "desc 1"},
new ItemLink {Description = "desc 2"},
};
var item = new Item
{
ItemLinks = links,
};
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ItemLink, ItemLink>(); // you can extend this part of the configuration here
cfg.CreateMap<Item, Item>();
cfg.CreateMap<ItemLink, MyCustomClass>()
.ForMember(myCustomClass => myCustomClass.DescriptionWithDifferentName,
expression => expression.MapFrom(itemLink => itemLink.Description));
// to map to a different type
// more configs can do here
// e.g. cfg.CreateMap<Item, SomeOtherClass>();
});
ItemLink linkClone = Mapper.Map<ItemLink>(links[0]);
ItemLink[] linkArrayClone = Mapper.Map<ItemLink[]>(item.ItemLinks);
Item itemClone = Mapper.Map<Item>(item);
MyCustomClass myCustomClassObject = Mapper.Map<MyCustomClass>(links[0]);
}
public class Item
{
public ItemLink[] ItemLinks { get; set; }
}
public class ItemLink
{
public string Description { get; set; }
}
public class MyCustomClass
{
public string DescriptionWithDifferentName { get; set; }
}
}
}
您还可以配置Automapper来使用cfg.CreateMissingTypeMaps = true;
自动创建丢失的地图cfg.CreateMissingTypeMaps = true;
using AutoMapper;
namespace Experiments
{
class Program
{
static void Main(string[] args)
{
var links = new ItemLink[]
{
new ItemLink {Description = "desc 1"},
new ItemLink {Description = "desc 2"},
};
var item = new Item
{
ItemLinks = links,
};
Mapper.Initialize(cfg =>
{
// now AutoMapper will try co create maps on it's own
cfg.CreateMissingTypeMaps = true;
// we can still add custom maps like that
cfg.CreateMap<ItemLink, MyCustomClass>()
.ForMember(myCustomClass => myCustomClass.DescriptionWithDifferentName,
expression => expression.MapFrom(itemLink => itemLink.Description));
});
ItemLink linkClone = Mapper.Map<ItemLink>(links[0]);
ItemLink[] linkArrayClone = Mapper.Map<ItemLink[]>(item.ItemLinks);
Item itemClone = Mapper.Map<Item>(item);
// without custom map myCustomClassObject.DescriptionWithDifferentName would be null
MyCustomClass myCustomClassObject = Mapper.Map<MyCustomClass>(links[0]);
}
public class Item
{
public ItemLink[] ItemLinks { get; set; }
}
public class ItemLink
{
public string Description { get; set; }
}
public class MyCustomClass
{
public string DescriptionWithDifferentName { get; set; }
}
}
}
我不确定我是否了解您的需求,我想您正在尝试从ItemLink列表映射到viewModel.ItemLink列表
所以Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
成为
var listOfViewModelItemLink = Mapper.Map<List<viewModel.ItemLink>>(db.ItemLinks);
您可以在listOfViewModelItemLink上调用ToArray(),然后将其分配给Item类的ItemLinks属性
我不确定,但是我想您正在尝试从ItemLink数组映射到viewModel.ItemLink数组。 您应该这样做:
var viewModels = db.ItemLinks
.ToArray()
.Select(x=>Mapper.Map<viewModel.ItemLink>(x))
.ToArray();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.