C# 使用AutoMapper映射类数组

C# 使用AutoMapper映射类数组,c#,asp.net,asp.net-mvc,automapper,C#,Asp.net,Asp.net Mvc,Automapper,我是AutoMapper的新手,正在尝试映射ArrayclassItemLink[] public class ViewModel { public ItemLink[] ItemLinks { get; set; } } public class ItemLink { public string Description { get; set; } } 我试过: Mapper.Map<viewModel.ItemLink>(db.ItemLinks); 因此,我想将Vi

我是AutoMapper的新手,正在尝试映射
Array
class
ItemLink[]

public class ViewModel
{
  public ItemLink[] ItemLinks { get; set; }
}

public class ItemLink
{
  public string Description { get; set; }
}
我试过:

Mapper.Map<viewModel.ItemLink>(db.ItemLinks);

因此,我想将
ViewModel.ItemLink[]
映射到
Db.ItemLink[]

您需要首先配置映射器

有两种可能的方法,静态和非静态。我倾向于非静态,因为它允许您创建多个映射器,可以使用不同的映射策略

非静态示例:

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; }
        }
    }
}

您需要首先配置映射器

有两种可能的方法,静态和非静态。我倾向于非静态,因为它允许您创建多个映射器,可以使用不同的映射策略

非静态示例:

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; }
        }
    }
}

不能像在
Mapper.Map(db.ItemLinks)中那样为泛型参数提供变量。它称为类型参数,并且必须是类型

正如@gisek在他的回答中提到的,您需要首先配置映射器。通常在应用程序启动时完成

可以考虑从DB中获取完整对象,但是您也可以选择使用可查询扩展,这些扩展仅用于获取视图模型所需的数据。

Mapper.Initialize(cfg => {
    cfg.CreateMap<DB.ItemLink, View.ItemLink>();
});
Mapper.Configuration.AssertConfigurationIsValid();
配置。我假设数据库中的实体有名称空间
DB
,视图模型有名称空间
View

Mapper.Initialize(cfg => {
    cfg.CreateMap<DB.ItemLink, View.ItemLink>();
});
Mapper.Configuration.AssertConfigurationIsValid();
Mapper.Initialize(cfg=>{
CreateMap();
});
Mapper.Configuration.AssertConfigurationsValid();
从数据库获取完整实体,然后将其映射到属性:

var viewModel = new View.Item();
viewModel.ItemLinks = Mapper.Map<View.ItemLink[]>(db.ItemLinks.ToArray());
var viewModel=newview.Item();
viewModel.ItemLinks=Mapper.Map(db.ItemLinks.ToArray());
项目实体从数据库到视图模型:

var viewModel = new View.Item();
viewModel.ItemLinks = db.ItemLinks.ProjectTo<View.ItemLink>().ToArray();
var viewModel=newview.Item();
viewModel.ItemLinks=db.ItemLinks.ProjectTo().ToArray();

您不能像在
Mapper.Map(db.ItemLinks)中那样为泛型参数提供变量。它称为类型参数,并且必须是类型

正如@gisek在他的回答中提到的,您需要首先配置映射器。通常在应用程序启动时完成

可以考虑从DB中获取完整对象,但是您也可以选择使用可查询扩展,这些扩展仅用于获取视图模型所需的数据。

Mapper.Initialize(cfg => {
    cfg.CreateMap<DB.ItemLink, View.ItemLink>();
});
Mapper.Configuration.AssertConfigurationIsValid();
配置。我假设数据库中的实体有名称空间
DB
,视图模型有名称空间
View

Mapper.Initialize(cfg => {
    cfg.CreateMap<DB.ItemLink, View.ItemLink>();
});
Mapper.Configuration.AssertConfigurationIsValid();
Mapper.Initialize(cfg=>{
CreateMap();
});
Mapper.Configuration.AssertConfigurationsValid();
从数据库获取完整实体,然后将其映射到属性:

var viewModel = new View.Item();
viewModel.ItemLinks = Mapper.Map<View.ItemLink[]>(db.ItemLinks.ToArray());
var viewModel=newview.Item();
viewModel.ItemLinks=Mapper.Map(db.ItemLinks.ToArray());
项目实体从数据库到视图模型:

var viewModel = new View.Item();
viewModel.ItemLinks = db.ItemLinks.ProjectTo<View.ItemLink>().ToArray();
var viewModel=newview.Item();
viewModel.ItemLinks=db.ItemLinks.ProjectTo().ToArray();

我假设您使用的是.net mvc

首先,您需要在应用程序启动时初始化映射,无需每次在控制器中进行初始化等

以下错误表示您没有初始化映射器,automapper不知道您的源对象和目标对象

错误:

Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
“映射程序未初始化。请使用适当的 配置。如果您试图通过 容器或其他,请确保您没有对 静态映射器.Map方法,如果您使用的是ProjectTo或 使用DataSource扩展方法,确保传入 适当的IConfigurationProvider实例。“

解决方案:

Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
在你的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 */ 
         });
    }
}
在控制器中

var-mappedArray=Mapper.Map(db.ItemLinks);

var-mappedArray=Mapper.Map(db.ItemLinks)//ItemLinks[]指的是您的dto。

我假设您使用的是.net mvc

首先,您需要在应用程序启动时初始化映射,无需每次在控制器中进行初始化等

以下错误表示您没有初始化映射器,automapper不知道您的源对象和目标对象

错误:

Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
“映射程序未初始化。请使用适当的 配置。如果您试图通过 容器或其他,请确保您没有对 静态映射器.Map方法,如果您使用的是ProjectTo或 使用DataSource扩展方法,确保传入 适当的IConfigurationProvider实例。“

解决方案:

Mapper.Map<viewModel.ItemLink>(db.ItemLinks);
在你的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 */ 
         });
    }
}
在控制器中

var-mappedArray=Mapper.Map(db.ItemLinks);

var-mappedArray=Mapper.Map(db.ItemLinks)//ItemLinks[]指的是您的dto。

我不确定我是否理解您的需求, 我猜您正在尝试从ItemLink列表映射到viewModel.ItemLink列表

所以
Mapper.Map(db.ItemLinks)

变成

var listOfViewModelItemLink = Mapper.Map<List<viewModel.ItemLink>>(db.ItemLinks);
var-listOfViewModelItemLink=Mapper.Map(db.ItemLinks);

您可以调用listOfViewModelItemLink上的ToArray(),然后将Item类的ItemLinks属性赋值给, 我猜您正在尝试从ItemLink列表映射到viewModel.ItemLink列表

所以
Mapper.Map(db.ItemLinks)

变成

var listOfViewModelItemLink = Mapper.Map<List<viewModel.ItemLink>>(db.ItemLinks);
var-listOfViewModelItemLink=Mapper.Map(db.ItemLinks);

您可以调用listOfViewModelItemLink上的ToArray(),然后分配给Item类的ItemLinks属性

我不确定,但我猜您正在尝试从ItemLink数组映射到viewModel.ItemLink数组。你应该这样做:

var viewModels = db.ItemLinks
        .ToArray()
        .Select(x=>Mapper.Map<viewModel.ItemLink>(x))
        .ToArray();
var viewModels=db.ItemLinks
.ToArray()
.Select(x=>Mapper.Map(x))
.ToArray();
我不确定,但我想