Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net core EFCore DotNet 5&;汽车制造商。映射虚拟集合_.net Core_Collections_Entity Framework Core_Automapper - Fatal编程技术网

.net core EFCore DotNet 5&;汽车制造商。映射虚拟集合

.net core EFCore DotNet 5&;汽车制造商。映射虚拟集合,.net-core,collections,entity-framework-core,automapper,.net Core,Collections,Entity Framework Core,Automapper,首先,我对Automapper还不熟悉,我发现官方文档至少可以说很差 我正在尝试映射两个具有虚拟集合的复杂实体,它们本身需要映射 Map 在每一行中,我需要映射 Map 这些类的一个非常简化的版本: 公共类ComplexEntityDb { 公共int Id; //为简洁起见,删除了多个属性(14) 公共虚拟ICollection CollectionDb{get;set;} } 公共类ComplexEntityVM { 公共int Id; //为简洁起见,删除了多个属性(7) 公共虚拟IC

首先,我对Automapper还不熟悉,我发现官方文档至少可以说很差

我正在尝试映射两个具有虚拟集合的复杂实体,它们本身需要映射

Map
在每一行中,我需要映射

Map
这些类的一个非常简化的版本:

公共类ComplexEntityDb
{
公共int Id;
//为简洁起见,删除了多个属性(14)
公共虚拟ICollection CollectionDb{get;set;}
}
公共类ComplexEntityVM
{
公共int Id;
//为简洁起见,删除了多个属性(7)
公共虚拟ICollection CollectionDb{get;set;}
}
公共类EntityCollectionItemDb
{
公共int Id;
//为简洁起见,删除了多个属性(12)
}
公共类EntityCollectionItemVM
{
公共int Id;
//为简洁起见,删除了多个属性(6)
}
使用AutoMapper 10.1.1和DI extensions 8.1.1在dotnet 5上使用EF Core 5.04执行此操作的正确方法是什么

我在这个网站上读了几十篇文章,似乎没有一个简单的方法可以做到这一点

提前感谢聪明人能给予的任何帮助

编辑:(摘自@dglozano答案的评论部分)-

我正在使用映射配置文件-

公共类映射配置文件:配置文件
{
公共映射配置文件()
{
CreateMap().ReverseMap();
CreateMap.ReverseMap();
} 
} 
和伊玛珀-

专用只读IMapper\u映射器;
公共定制服务(IMapper映射器)
{
_映射器=映射器;
} 
努力-

return\u mapper.Map(源代码);

结果:
EntityCollectionItemVM
集合为空。

您只需要定义每个元素类型的映射,如下所示。您必须告诉Automapper如何映射
ComplexEntityDb->ComplexEntityVM
,以及如何映射
EntityCollectionItemDb->EntityCollectionItemVM
,然后告诉所有人

因此,在您的案例中,最简单的示例如下所示:

using System;
using AutoMapper;
using System.Collections.Generic;

public class ComplexEntityDb
{
    public ComplexEntityDb(int id)
    {
        Id = id;
        var item1 = new EntityCollectionItemDb();
        var item2 = new EntityCollectionItemDb();
        item1.Id = id * 1000 + 1;
        item2.Id = id * 1000 + 2;
        CollectionDb = new List<EntityCollectionItemDb>{item1, item2, };
    }

    public int Id
    {
        get;
        set;
    }

    // Multiple properties (14) removed for brevity
    public ICollection<EntityCollectionItemDb> CollectionDb
    {
        get;
        set;
    }
}

public class ComplexEntityVM
{
    public int Id;
    // Multiple properties (7) removed for brevity
    public ICollection<EntityCollectionItemVM> CollectionDb
    {
        get;
        set;
    }
}

public class EntityCollectionItemDb
{
    public int Id;
// Multiple properties (12) removed for brevity
}

public class EntityCollectionItemVM
{
    public int Id;
// Multiple properties (6) removed for brevity
}

public class Program
{
    public static void Main()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<ComplexEntityDb, ComplexEntityVM>();
            cfg.CreateMap<EntityCollectionItemDb, EntityCollectionItemVM>();
        });
        var complexEntity1 = new ComplexEntityDb(1);
        var complexEntity2 = new ComplexEntityDb(2);
        var complexEntity3 = new ComplexEntityDb(3);
        var source = new List<ComplexEntityDb>{complexEntity1, complexEntity2, complexEntity3};
        var mapper = config.CreateMapper();
        var dest = mapper.Map<IEnumerable<ComplexEntityDb>, IEnumerable<ComplexEntityVM>>(source);
        
        foreach(var parentMapped in dest)
        {
            Console.WriteLine("Mapped parent Id {0}", parentMapped.Id);
            foreach(var childMapped in parentMapped.CollectionDb)
            {
                Console.WriteLine("  - Mapped child Id {0}", childMapped.Id);
            }
            Console.WriteLine();
        }
    }
}


在更真实的场景中,这将是相同的想法,但我将创建一个来定义每个映射配置,然后使用注入的
IMapper
执行映射。

我使用的是映射配置文件公共类MappingProfile:profile{public MappingProfile(){CreateMap().ReverseMap();CreateMap).ReverseMap();}}和Imapper:private readonly Imapper\u mapper;publiccustomservice(IMapper-mapper){{u-mapper=mapper;}并尝试:返回{u-mapper.Map(源代码);结果:EntityCollectionItemVM集合为空。是否可以编辑您的问题并在其中添加配置文件配置@MaxTheCoder@MaxTheCoder您是否仔细检查了源是否有非空的子集合?可能您在EF查询中缺少
。Include(x=>x.YourChildCollection)
。您的映射配置似乎是正确的,您可以在我创建的最小fiddle示例中检查是否正在映射子集合。。。。因此,如果您的查询正确,并且您的源集合已加载(包括)相关集合,那么映射应该可以工作。我无法编辑原始问题,它一直告诉我代码太多。任何额外的文本都不允许我保存。我已经验证了来自db的源数据是否正确包含所需的集合首先想到的是,您可能应该尝试使用
ProjectTo
而不是
Map
source
是否为
IQueryable
?还是在映射之前要具体化查询结果?@MaxTheCoder,你明白了吗?通过复制DB模型创建了新的VM模型,并测试了映射程序,结果如预期一样。因此映射配置是正确的@dglozano的IQueryable评论让我深思,经过一番深思熟虑后,发现EntityCollectionItemVM有自己的子集合,它是IEnumerable,但它的DB对应项是ICollection。这似乎是导致错误的原因。翻阅文档,ICollection继承IEnumerable,因此您可以一种方式映射,但不能另一种方式映射。将DB模型更改为IEnumerable,现在可以使用了。非常感谢您的投入。
Output:

Mapped parent Id 1
  - Mapped child Id 1001
  - Mapped child Id 1002

Mapped parent Id 2
  - Mapped child Id 2001
  - Mapped child Id 2002

Mapped parent Id 3
  - Mapped child Id 3001
  - Mapped child Id 3002