如何解决如何使用LINQ查询列出清单?
我试图返回一个列表,该列表是从该查询中获得的, 但出现错误:
无法从'System.Collections.Generic.List >'转换为'System.Collections.Generic.IReadOnlyList
'[HOLMES.DocCognition.Application] csharp(CS1503)“
我是C#和Linq的新手。请帮助解决此问题。
public async Task<ListResultDto<DashboardCountDto>> CountAllTrainDocuments()
{
var retList = new List<DashboardCountDto>();
var allTrainFiles = await _trainDocumentRepository.GetAllListAsync();
var CountTrainFiles = allTrainFiles.GroupBy(t=> t.DocumentTypeName).
Select(e => new {
//count = e.Count(),DocumentTypeName = e.Key,ProcessedDocument = e.Count(g => g.Processed = true),UnProcessedDocument = e.Count(g => g.Processed = false),}).ToList();
Dictionary<string,int> innerDict = new Dictionary<string,int>();
Dictionary<string,string> outterDict = new Dictionary<string,string>();
// return retList;
CountTrainFiles.ForEach(
row => Console.WriteLine($"DocType: {row.DocumentTypeName},ProcessedDocument: {row.ProcessedDocument},UnProcessedDocument: {row.UnProcessedDocument}"));
return new ListResultDto<DashboardCountDto>(CountTrainFiles);
我的DTO如下:
public class DashboardCountDto : EntityDto<long>
{
public string DocumentTypeName { get; set; }
public int ProceesedDocumentCount { get; set; }
public int UnProceesedDocumentCount { get; set; }
}
解决方法
此:
new
{
//count = e.Count(),DocumentTypeName = e.Key,ProcessedDocument = e.Count(g =>g.Processed = true),UnProcessedDocument = e.Count(g =>g.Processed = false),}
创建一个anonymous object,其结构上看起来 是DashboardCountDto
,但不是DashboardCountDto
。通过使用new
之后的类名来创建一个真实的类:
new DashboardCountDto
{
//count = e.Count(),}
,
简短答案:
将您的Selecte(e => new {
更改为Selecte(e => new DashboardCountDto {
那将解决您的问题。
更长的答案:
您的查询效率不高。
数据库管理系统经过优化,可以执行数据库查询。数据库查询的最慢部分是将所选数据从DBMS传输到本地进程。因此,您应该尝试让您的DBMS完成所有处理,并尝试将所有传输的数据限制为DBMS无法再处理的数据。
首先,您获取所有训练文件的所有属性,并将它们放在列表中。然后,您的本地进程将提取的训练文件分组为具有相同DocumentTypeName的训练文件组。在每组训练文件中,您丢弃的大多数东西,仅计算哪些已处理,哪些未处理。
让DBMS这样做更有效。查看您的存储库是否有返回IQueryable<TrainFile>
而不是Task<List<TrainFile>>
的方法。如果存储库中没有该存储库,请考虑将其添加到您的存储库中。
IQueryable<TrainFile> trainFiles = trainDocumentRepository.TrainFiles();
// make groups of TrainFiles with Same documentName and count the number of Processed:
var groups = trainFiles.GroupBy(trainFile => trainFile.DocumentName,// Parameter resultSelector: use each DocumentName,and all TrainFiles that have this
// value of DocumentName to make one new DashboardCountDto
(documentName,trainFilesWithThisDocumentName) => new DashboardCountDto
{
DocumentTypeName = documentTypeName,Processed = trainFilesWithThisDocumentName
.Where(trainFile => trainFile.Processed)
.Count(),UnProcessed = trainFilesWithThisDocumentName
.Where(trainFile => !trainFile.Processed)
.Count(),});
注意:每个trainFileWithThisDocumentName扫描两次:一次计数已处理的训练文件,一次计数未处理的训练文件。 sub-GroupBy将解决此问题:
(documentName,trainFilesWithThisDocumentName) => new
{
DocumentName = documentName,SubGroups = trainFilesWithThisDocomentName.GroupBy(trainFile => trainFile.Processed,// Parameter resultSelector:
(processed,trainFilesWithThisValueOfProcessed) => new
{
Processed = processed,Count = trainFilesWithThisValueOfProcessed.Count(),})
.OrderByAscending(subGroup => subGroup.Processed)
.ToList(),}),
因此,现在每个DocumentName都有一个对象,其中包含DocumentName,以及一个属性SubGroups,该属性是两个对象的列表:一个具有Process true,一个具有此DocumentName的所有训练文件的计数,另一个具有Count处理false,并计算所有未处理的具有此DocumentName的火车文件。 [0]包含处理为假的组,[1]包含处理为真的组。
要使子组为带有thisDocumentNames的trainFiles仅被扫描一次。
一次最终选择将使您的查询完成:
.Select(group => new DashboardCountDto
{
DocumentName = group.DocumentName,UnProcessed = group.SubGroup[0].Count,Processed = group.SubGroup[1].Count,})
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。