C#自动Map器“不支持的Map”,带有< dynamic>LinQ查询的列表结果

g2ieeal7  于 2022-12-06  发布在  C#
关注(0)|答案(2)|浏览(185)

给定下一个工作LinQ查询:

var catalogues = (from cat in db.CATALOGUES

                      join doc in db.DOCUMENTS_CATALOGS on
                      new { a = cat.PFK_ENTERPRISE, b = cat.FK_DOCUMENT_VIDEO }
                      equals
                      new { a = doc.PFK_ENTERPRISE, b = (int?)doc.PK_DOCUMENT }

                      join pos in db.DOCUMENTS_CATALOGS on
                      new { a = cat.PFK_ENTERPRISE, b = cat.FK_DOCUMENT }
                      equals
                      new { a = pos.PFK_ENTERPRISE, b = (int?)pos.PK_DOCUMENT }

                      where (cat.PFK_ENTERPRISE == enterpriseId && cat.PK_CATALOGUE == catalogueId)
                      orderby cat.DESC_CATALOGUE ascending
                      select new
                      {
                          cat.PK_CATALOGUE,
                          cat.FK_DOCUMENT_VIDEO,
                          cat.DESC_CATALOGUE,
                          doc.REAL_NAME,
                          doc.SERVER_NAME_ORIGINAL_FILE,
                          POSTER = pos.SERVER_NAME_ORIGINAL_FILE
                      });

它会产生一个List Anonymous结果,如下所示(在我的案例中有1条记录):

{ 
    PK_CATALOGUE = 212, 
    FK_DOCUMENT_VIDEO = 212, 
    DESC_CATALOGUE = "xxx", 
    REAL_NAME = "7_Category_Image_c3ab57e3-ec7e-4a80-aaa1-c6cc10a1b917.jpg", 
    SERVER_NAME_ORIGINAL_FILE = "7_Category_Image_c3ab57e3-ec7e-4a80-aaa1-c6cc10a1b917.jpg", 
    POSTER = "7_IMG_CATALOGUE_5d8e24eb-8a40-4e4d-9d86-a3f610d5b65e.jpg" 
}

我试着把它Map到下一个对象:

public class VideoGalleryVM
{
    public int PK_CATALOGUE { get; set; }
    public int? FK_DOCUMENT_VIDEO { get; set; }
    public string DESC_CATALOGUE { get; set; }
    public string REAL_NAME { get; set; }
    public string SERVER_NAME_ORIGINAL_FILE { get; set; }
    public string POSTER { get; set; }
}

接下去道:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<object, VideoTrainingVM>().ReverseMap();
});

IMapper mapper = config.CreateMapper();

List<VideoGalleryVM> vgVM = mapper.Map<List<VideoGalleryVM>>(videoGallery);

但无论我尝试什么,我都会得到一个“无效Map”类型的异常。
我不介意是否使用Automapper,只需要将LinQ查询的返回(即List动态)转换为View Model对象,并且:

var test1 = catalogues.ToList().Cast<VideoGalleryVM1>().ToList();

以无效的强制转换异常结束,并且

var test2 = catalogues.OfType<VideoGalleryVM1>().ToList();

以0个元素的列表结束。

hs1ihplo

hs1ihplo1#

你不需要为所有的事情都使用自动Map器,它是为简单的场景而创建的-Map相似的已知对象到另一个对象,如果Map简单的话更好。如果你通过Select进行投影-你可以在一个地方Map所有你需要的东西,而不需要使用自动Map器的“魔力”。
因此,只需将结果投影到所需的对象类型中:

var catalogues = 
    from cat in db.CATALOGUES

    join doc in db.DOCUMENTS_CATALOGS on
    new { a = cat.PFK_ENTERPRISE, b = cat.FK_DOCUMENT_VIDEO }
    equals
    new { a = doc.PFK_ENTERPRISE, b = (int?)doc.PK_DOCUMENT }

    join pos in db.DOCUMENTS_CATALOGS on
    new { a = cat.PFK_ENTERPRISE, b = cat.FK_DOCUMENT }
    equals
    new { a = pos.PFK_ENTERPRISE, b = (int?)pos.PK_DOCUMENT }

    where (cat.PFK_ENTERPRISE == enterpriseId && cat.PK_CATALOGUE == catalogueId)
    orderby cat.DESC_CATALOGUE ascending
    select new VideoGalleryVM
    {
        PK_CATALOGUE = cat.PK_CATALOGUE,
        FK_DOCUMENT_VIDEO = cat.FK_DOCUMENT_VIDEO,
        DESC_CATALOGUE = cat.DESC_CATALOGUE,
        REAL_NAME = doc.REAL_NAME,
        SERVER_NAME_ORIGINAL_FILE = doc.SERVER_NAME_ORIGINAL_FILE,
        POSTER = pos.SERVER_NAME_ORIGINAL_FILE
    };

强烈推荐阅读Automapperr创建者的文章,何时使用或不使用他的库。文章的目的是在以后支持Map时停止使用库:AutoMapper Usage Guidelines

tcbh2hod

tcbh2hod2#

我找到的将动态列表(LinQ查询的结果)转换为视图模型对象的唯一解决方案是:

var targetList = catalogues.Select(cat => new VideoGalleryVM() 
                { 
                    PK_CATALOGUE = cat.PK_CATALOGUE,
                    FK_DOCUMENT_VIDEO = cat.FK_DOCUMENT_VIDEO,
                    DESC_CATALOGUE = cat.DESC_CATALOGUE,
                    REAL_NAME = cat.REAL_NAME,
                    SERVER_NAME_ORIGINAL_FILE = cat.SERVER_NAME_ORIGINAL_FILE,
                    POSTER = cat.SERVER_NAME_ORIGINAL_FILE
                }).ToList();

我不认为这是最好的选择,甚至不明白为什么自动Map器(或其他类型的铸造)不会工作,但这只是工作。
在我的例子中,我们谈论的是一个没有那么多属性的类,但是想象一个长类...这就是Automapper应该做的。

相关问题