2016-01-13 43 views
1

作为后续到this question,我需要在MongoDB中聚合内部数组,我试图在LINQ中完成相同的任务。使用LINQ在对象列表内部聚合列表

我靠近,我已经找到了如何聚合在一个单独的项目:

// Get collection 
var collection = _database.GetCollection<VehicleDataUpload>("Vehicles"); 

// Get first project that meets our identifier 
var firstProject = collection.AsQueryable().Where(i => i.ProjectId.Equals("1234")).First(); 

// Get a list of DailySummaryData objects 
var aggregation = 
    from entry in firstProject.VehicleEntries 
    group entry by entry.Data 
    into result 
    select new DailySummaryData() { 
     ProjectName = firstProject.ProjectId, 
     Date = result.FirstOrDefault().Date, 
     Passed = result.Sum(x => (x.VehicleStatus.Equals("PASSED") ? 1 : 0)), 
     Failed = result.Sum(x => (x.VehicleStatus.Equals("FAILED") ? 1 : 0)) 
    }; 

return aggregation.ToList(); 

但是,我不能收集使用...First(),因为有可能是一个项目中多个VehicleDataUploads。如何汇总返回的文档列表中的所有列表?

+0

有什么问题吗?你不想过滤一个Project ID,但是对于所有的项目都有相同的结果?正确? – user449689

+0

关闭!我需要按项目ID过滤,但可能会返回多个文档。所以当我调用'var firstProject = collection.AsQueryable()。Where(i => i.ProjectId.Equals(“1234”))。First();'我宁愿能说'var uploads = collection.AsQueryable ().Where(i => i.ProjectId.Equals(“1234”))。ToList()'然后执行与上面相同的聚合,但对于'uploads'中的*每个元素*。这更清楚吗? – AdamMc331

+0

你试过删除'.First()?' –

回答

1

试试如下:

// Get collection 
var collection = _database.GetCollection<VehicleDataUpload>("Vehicles"); 

// Get first project that meets our identifier 
var aggregation = collection 
    .AsQueryable() 
    // This will return an IEnumerable of Vehicles object 
    .Where(i => i.ProjectId.Equals("1234")) 
    // Assuming you want to return a plain list, you should use SelectMany 
    .SelectMany(v => v.VehicleEntries 
     // You group each list of VehicleEntries 
     .GroupBy(ve => ve.Data) 
     // For each group you return a new DailySummaryData object 
     .Select(g => new DailySummaryData() { 
      ProjectName = v.ProjectId, 
      Date = g.Key, 
      Passed = g.Sum(x => (x.VehicleStatus.Equals("PASSED") ? 1 : 0)), 
      Failed = g.Sum(x => (x.VehicleStatus.Equals("FAILED") ? 1 : 0)) 
     }) 

return aggregation.ToList(); 
+0

哇,谢谢! * only *问题是我不能'ProjectName = v.ProjectId'我相信因为v现在已经超出了范围。我尝试使用输入字符串手动设置它:'ProjectName = argumentPassedToMethod',但是这给了我一个MongoCommandException,说聚合字段不以$开头。 – AdamMc331

+0

无论如何,我会接受这一点,因为它做了我想要的。我只需要找到将项目名称添加到结果项目的正确方法。 – AdamMc331

+0

考虑到你的组中有任何对象的信息,所以你可以尝试类似g.First()。ProjectId。 – user449689