问题描述
我刚刚完成了一个解决方案,但是客户要求对结果实施许多过滤器。
在这种情况下,客户需要过滤处于他们选择的任何状态的所有订单。
总而言之,这是我在使用实体框架和lambda语法查询和筛选时遇到问题的表的示例。
- 每个投诉都有说明和插入日期。
- 用户可以更改投诉状态。该更改记录在中间表
ComplaintStatus
中
Status
表具有所有可能的状态,记录为“待命”,“待修复”,“正在交货”等
如您所见,这是多对多的关系,因为我们在许多情况下都会有很多投诉。
此外,投诉可以更改为状态ID 1,然后更改为状态ID 2,然后返回状态1,所有记录都记录在ComplaintStatus
中间表中,从而避免了删除。
因此,对于过滤器,我需要找到Status
中的最后一个Complaint
。
这是我的代码的一部分:
var query = dbContext.Complaint // To get the Complaints table
.Include(c => c.ComplaintStatus) // To get the ComplaintStatus table
.Include(s => d.ComplaintStatus.Select(st => st.Status)) // To get the Status table
.AsQueryable();
var complaintId = 0;
var statusId = 0;
// As per my research we need to check if the filters variables has values or return all
// if we do not have filters in place.
// For this,I check if any filter has a value different than 0 and also re-check in the where
// clause if I need to filter by that specific item
if (complaintId || statusId)
{
query = query.Where(x => (
// This returns perfectly
(complaintId && x.Id.Equals(complaintId))
// This is where I'm totally stuck with no clue on how to search for the last Complaint Status equal to the designated statusId
|| (statusId && ((x.Complaint.GroupBy(c => c.id)
.Select(co => co.OrderByDescending(co => co.InsertDate).FirstOrDefault()) )
.Any(s => s.StatusId.Equals(statusId))
)
)
}
// Finally I fire the DB request
var response = query.ToListAsync();
EF抱怨我无法在where内执行和排序
我发现的一种可能的解决方案是在where子句Subquery in Where Clause of LINQ statement
中使用委托是否有精通EF的开发人员可以帮助实现这一目标?
干杯
解决方法
我只是利用一位同事的建议找到了一个解决方案。
在表ComplaintStatus中添加一列以标记状态是否为最后一个。 新列名称为Active,类型为bit,默认值为1
每次状态更改时,首先搜索所有先前的状态,并将“活动”列更改为0。在发生这种情况时,我也标记dateTime。 第二,我插入新的状态关系,并且该列的默认值为1,这将是唯一具有活动标记的状态。
这是查找投诉的最新状态的查询:
import sys
print(len(sys.stdin.read()))
如果您知道如何在动态where子句中执行select + orderBy,请发表评论,因为这对于这种复杂的搜索非常有帮助
欢呼
,好吧,好吧……幸运的是,我进入了该查询的解决方案…… 希望这能帮助其他人陷入困境。
要查找中间表的最后一条记录,我们可以使用MAX动词并再次比较日期,如下所示:
if (complaintId || statusId)
{
query = query.Where(x => (
// This returns perfectly
(complaintId && x.Id.Equals(complaintId))
// This is where I'm totally stuck with no clue on how to search for the last Complaint Status equal to the designated statusId
|| (statusId && ((x.Complaint.Any(y => (y.InsertDate == x.ComplaintStatus.Max(f => f.InsertDate))))
)
)
))
}