C# 使用Linq检查孙子列表时删除子列表项
以下代码显示如何将数据分配到C# 使用Linq检查孙子列表时删除子列表项,c#,linq,C#,Linq,以下代码显示如何将数据分配到IEnumerable 有一个列表(IEnumerable)有另一个列表(list),该子列表(list)上有一个列表。但是AllocationDetailList只有一个列表项 public IEnumerable<UnCompletedJobDetailsBO> GetControlDetails(DateTime startDate) { var controlDetails = (from booking in db.Book
IEnumerable
有一个列表(IEnumerable
)有另一个列表(list
),该子列表(list
)上有一个列表。但是AllocationDetailList
只有一个列表项
public IEnumerable<UnCompletedJobDetailsBO> GetControlDetails(DateTime startDate)
{
var controlDetails =
(from booking in db.BookingDetail
where booking.BookingDateTime >= startDate
orderby booking.DocketNo
select new UnCompletedJobDetailsBO()
{
CustomerName = booking.Customer.Name,
CompanyName = booking.CompanyDetail.Name,
JobList =
(from job in db.BookingJob.Where(x => x.BookingID == booking.BookingID) //get job list
select new JobDetailsBO()
{
JobID = job.JobID,
JobType = job.JobType,
ItemName = job.ItemName,
AllocationDetailList =
(from jobAllocationDetail in db.JobAllocation
join returnUnCollected in db.JobReturnUnCollected
on jobAllocationDetail.JobAllocationDetailID
equals returnUnCollected.JobAllocationDetailID
into returnJob
from returnUnCollected in returnJob.DefaultIfEmpty()
where (jobAllocationDetail.Booking.BookingID == booking.BookingID)
select new AllocationBO()
{
JobUnCollectedID = returnJob.JobUnCollectedID,
JobType = jobAllocationDetail.JobType,
CurrentStatus = jobAllocationDetail.CurrentStatus,
}).DefaultIfEmpty().ToList(),
}).DefaultIfEmpty().ToList(),
}).ToList();
return controlDetails;
}
如果没有,我不确定是否可以解决任何性能问题。要完全理解问题本身是很困难的,但是如果不能实际测试代码、复制和观察特定的性能问题,就很难确定您的问题具体在哪里,更不用说如何解决它了
也就是说,从您发布的代码中,可以清楚地看出为什么没有从列表中删除项目。基本问题是,虽然SelectMany()
方法确实允许您将所有不同JobList
对象中的所有元素作为单个枚举枚举,但这些元素将作为新枚举枚举
当您调用ToList()
时,您正在从该新枚举创建一个全新的列表,而当您调用RemoveAll()
时,您只是在从该新列表中删除元素,而不是它们最初来自的列表
您说您可以让它与for
循环一起工作。我想你的意思是这样的:
public List<UnCompletedJobDetailsBO> RemovePODFromSelectedList(
List<UnCompletedJobDetailsBO> unCompletedJobDetailsBO)
{
foreach (var item in unCompletedJobDetailsBO)
{
item.JobList.RemoveAll(x => ((x.AllocationDetailList[0] != null) ?
x.AllocationDetailList[0].JobType == "D" &&
x.AllocationDetailList[0].JobUnCollectedID == null &&
x.AllocationDetailList[0].CurrentStatus == 5 :
x.AllocationDetailList.Count > 1));
}
return unCompletedJobDetailsBO;
}
public List从selectedlist中删除pod(
列出未完成的作业详细信息(SBO)
{
foreach(未完成的JobDetailsBO中的var项)
{
item.JobList.RemoveAll(x=>((x.AllocationDetailList[0]!=null))是否为空?
x、 AllocationDetailList[0]。作业类型==“D”&&
x、 AllocationDetailList[0]。JobUnCollectedID==null&&
x、 AllocationDetailList[0]。CurrentStatus==5:
x、 AllocationDetailList.Count>1);
}
返回未完成的JobDetailsBO;
}
注意:不需要返回未完成的ObjDetailsBO
。整个对象是不变的,更不用说变量了。代码唯一要修改的是传入对象成员中的每个作业列表
对象。也就是说,上述方法实际上可以有一个返回类型void
,并且可以完全删除return
语句
您可以通过以不同的方式删除元素来加快代码的速度。List.RemoveAll()
方法实际上相当有效,成本为O(n)。但它仍然需要在删除第一个元素后复制列表中的所有数据(以便所有元素在列表中下移)。如果您必须对列表进行排序,这可能是您所能做的最好的事情,但是如果没有,您可以以不同的方式处理删除,或者使用不同的数据结构,在无序的情况下删除一个或多个元素的成本更低
但是,没有更多的细节,也没有一个很好的例子来解决这个特定的问题,在这里似乎是不现实的
x.AllocationDetailList[0] != null
如果AllocationDetailList中没有项,将引发异常。相反,你需要检查一下
x.AllocationDetailList!=null && x.AllocationDetailList.Count>0.
另外,在代码中选择many后的.ToList()将创建一个新列表,项目将从该新列表中删除,而不是从未完成的ObjDetailsBO中删除。您需要修改删除功能,如下所示
unCompletedJobDetailsBO.ForEach(y => y.JobList.RemoveAll(x => ((x.AllocationDetailList != null && x.AllocationDetailList.Count>0)
?
x.AllocationDetailList[0].JobType == "D"
&& x.AllocationDetailList[0].JobUnCollectedID == null
&& x.AllocationDetailList[0].CurrentStatus == "5"
:
x.AllocationDetailList.Count > 1
)
));
很抱歉,没有提供完整的代码。此代码位于同一DA文件中。我想将筛选后的列表放入我的控制器。我同意你的回答。如果没有forloop/foreach,我就做不到?考虑到目前为止提供的信息,不……如果不访问主列表中的每个
UnCompletedJobDetailsBO
对象,我看不到一种方法可以做到这一点。请注意,即使您的非工作示例也确实做到了这一点……它只是以一种不太明显的方式做到了这一点。它在过滤之前加载所有列表。这与使用foreach相同。在延迟/延迟级别,这是任何可能的方法。删除所有需要列表。谢谢。我不知道你说的“懒惰/延迟级别”是什么意思。但是,您可以通过删除最后一个ToList()
来推迟原始查询,并且您可以在作业列表
属性的初始化中添加where
,以考虑您想要执行的一些筛选,这样元素就不会首先出现在列表中。我不清楚你问的是什么。我的第一个错误是在查询中使用ToList()。如果我没有使用ToList,我的输出应该是IEnumerable。但无法对IEnumerable应用RemoveAll()。有没有办法从IEnumerable中删除项而不应用查询中的where
unCompletedJobDetailsBO.ForEach(y => y.JobList.RemoveAll(x => ((x.AllocationDetailList != null && x.AllocationDetailList.Count>0)
?
x.AllocationDetailList[0].JobType == "D"
&& x.AllocationDetailList[0].JobUnCollectedID == null
&& x.AllocationDetailList[0].CurrentStatus == "5"
:
x.AllocationDetailList.Count > 1
)
));