2017-10-06 104 views
1

我有在LINQ过滤数据有问题的值的数据,这里是我的模型:LINQ如何筛选基于性能

public class CoursePlan 
    { 
     [PrimaryKey, AutoIncrement] 
     public int Id { get; set; } 
     public string Semester { get; set; } 
     public string ModuleCode { get; set; } 
     public string ModuleName { get; set; } 
     public string Credits { get; set; } 
     public string OrderNumber { get; set; } 
     public string ModuleStatus { get; set; } 

    } 

,这里是我的数据Json

enter image description here

这里的问题有些模块具有相同的OrderNumber这意味着它们是可选的,学生必须研究其中的一个,如果学生已经学习其中之一,我应该忽略同一订单号中的其他模块。

以其他方式来描述这个问题

我想回到CoursePlan和这个名单上的列表中是否存在具有相同OrderNumber检查ModuleStatus对于他们中的每一个,如果两个项目

任何一个Completed删除该订单上的其他模块将全部退回。

这里是我的代码

var coursePlanList = await _sqLiteAsyncConnection.Table<CoursePlan>().ToListAsync(); 
var groupedData = coursePlanList.OrderBy(e => e.Semester) 
    .GroupBy(e => e.OrderNumber) 
    .Select(e => new ObservableGroupCollection<string, CoursePlan>(e)) 
    .ToList(); 

通过这种算法,现在的IM解决这一点,不知道这是否是最好的

var coursePlanList = await _sqLiteAsyncConnection.Table<CoursePlan>().ToListAsync(); 

    List<CoursePlan> finalList = new List<CoursePlan>(); 

    var counter = 0; 
    foreach (var itemPlan in coursePlanList) 
    { 
     if (counter > 0 && counter < coursePlanList.Count) 
      if (itemPlan.OrderNumber == coursePlanList[counter - 1].OrderNumber) 
      { 
       if (itemPlan.ModuleStatus == "Completed") 
       { 
        finalList.RemoveAll(a => a.OrderNumber == itemPlan.OrderNumber); 
        finalList.Add(itemPlan); 
       } 
       Debug.WriteLine(itemPlan.ModuleName + "With -->" + coursePlanList[counter - 1].ModuleName); 
      } 

      else 
       finalList.Add(itemPlan); 

     counter++; 
    } 

    var groupedData = finalList.OrderBy(e => e.ModuleStatus) 
     .ThenBy(e => e.Semester) 
     .GroupBy(e => e.Semester) 
     .Select(e => e) 
     .ToList(); 

    CoursePlanViewList.BindingContext = new ObservableCollection<IGrouping<string, CoursePlan>>(groupedData); 

任何建议或指导,将不胜感激

+0

我怀疑这个复杂的东西不能单独使用LINQ来完成,或者至少不能在单个查询中完成。但是一些LINQ专家可能会证明我错了。 – Jason

+0

我在考虑将列表分成两个列表,但这会影响处理速度,也不能按我期望的那样工作,顺便说一句,其他专家 –

回答

2

让我改述你的要求:你想显示所有的计划p呃OrderNumber满足条件:他们的小组计划都不应该是“完成”或计划本身应该是“完成”。这一切分组由Semester

var plansQuery = 
from p in _sqLiteAsyncConnection.Table<CoursePlan>() 
group p by p.Semester into sem 
select new 
{ 
    PlansInSemester = 
     from p in sem 
     group p by p.OrderNumber into gp 
     select new 
     { 
      PlansInOrderNumber = 
       gp.Where(p => !gp.Any(p1 => p1.ModuleStatus == "Completed") 
          || p.ModuleStatus == "Completed") 
     } 
}; 

这使你产生你要选择的课程计划的IQueryable,但在两个级别进行分组,因此被压扁查询两次,得到的最终结果是:

var coursePlanList = await plansQuery 
    .SelectMany(x => x.PlansInSemester 
     .SelectMany(y => y.PlansInOrderNumber)).ToListAsync() 
+0

每个学期的每个模块都有唯一的orderNumber,如果2个模块具有相同的OrderNumber,则意味着一个如果是,则有两个或三个模块具有相同的订单,其中一个订单状态已完成,则忽略该订单上的其他模块并返回已完成订单,否则,如果所有三个订单完全相同且没有任何订单完成,然后返回它们,希望你明白我的意思 –

+0

这个查询是否提供了预期的输出?我想我跟着你,但根据我的理解,查询完全符合你的要求。 –

+0

我用我的基本解决方案修改了我的问题,也许你会从我的解决方案中理解我的要求我已经尝试过您的查询,1:仅返回学期和计划对象,我修改它但未获取预期值,如果可以使查询返回整个属性, –