C# Automapper "Unsupported Mapping" 与 LinQ 查询的 List<dynamic> 结果
C# Automapper "Unsupported Mapping" with List<dynamic> result of LinQ query
鉴于下一个工作 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
});
这会产生一个匿名列表的结果,其中包含类似这样的内容(我的情况下有 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"
}
我正在尝试将其映射到下一个对象:
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);
但是无论我尝试什么,我都会得到一个类型为“无效映射”的异常。
我不介意使用或不使用Automapper,只需要将LinQ查询(即动态列表)的return转换为View Model对象,并且:
var test1 = catalogues.ToList().Cast<VideoGalleryVM1>().ToList();
以无效的转换异常结束并且
var test2 = catalogues.OfType<VideoGalleryVM1>().ToList();
以包含 0 个元素的列表结束。
好吧,经过几个小时的努力,我发现将我的动态列表(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();
我认为这不是最佳选择,甚至不明白为什么 Automapper(或其他类型的转换)不起作用,但这确实有效。
在我的例子中,我们谈论的 class 没有那么多属性,但是图像很长 class...这就是 Automapper 应该做的。
我希望这对其他人有所帮助。
您不需要为所有事情使用 Automapper,它是为简单场景创建的 - 将相似的已知对象映射到另一个对象,如果映射简单则更好。如果您通过 Select
进行投影 - 您可以在一个地方映射您需要的所有内容,而无需使用 Automapper 的“魔法”。
因此只需将您的结果投影到所需的对象类型即可:
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 的创建者关于何时使用或不使用他的库的文章。创建文章是为了在以后难以支持映射的情况下停止使用库:AutoMapper Usage Guidelines
鉴于下一个工作 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
});
这会产生一个匿名列表的结果,其中包含类似这样的内容(我的情况下有 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"
}
我正在尝试将其映射到下一个对象:
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);
但是无论我尝试什么,我都会得到一个类型为“无效映射”的异常。
我不介意使用或不使用Automapper,只需要将LinQ查询(即动态列表)的return转换为View Model对象,并且:
var test1 = catalogues.ToList().Cast<VideoGalleryVM1>().ToList();
以无效的转换异常结束并且
var test2 = catalogues.OfType<VideoGalleryVM1>().ToList();
以包含 0 个元素的列表结束。
好吧,经过几个小时的努力,我发现将我的动态列表(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();
我认为这不是最佳选择,甚至不明白为什么 Automapper(或其他类型的转换)不起作用,但这确实有效。
在我的例子中,我们谈论的 class 没有那么多属性,但是图像很长 class...这就是 Automapper 应该做的。
我希望这对其他人有所帮助。
您不需要为所有事情使用 Automapper,它是为简单场景创建的 - 将相似的已知对象映射到另一个对象,如果映射简单则更好。如果您通过 Select
进行投影 - 您可以在一个地方映射您需要的所有内容,而无需使用 Automapper 的“魔法”。
因此只需将您的结果投影到所需的对象类型即可:
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 的创建者关于何时使用或不使用他的库的文章。创建文章是为了在以后难以支持映射的情况下停止使用库:AutoMapper Usage Guidelines