繁体   English   中英

使用AutoMapper映射类数组

[英]Mapping class array using AutoMapper

我是AutoMapper的新手,并尝试映射ArrayItemLink[]

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM