如何解决LINQ / Lambda表达式:连接列表并使用给定公式查找数据的平均计数
我有500多个 EventData 记录的列表。 EventData 的模型如下所示
[[[ 0 1 2]
[ 9 10 11]
[18 19 20]]
[[ 1 2 3]
[10 11 12]
[19 20 21]]
[[ 2 3 4]
[11 12 13]
[20 21 22]]]
此处的EventId可以为1,2,3,4和5(枚举)。从此列表中,我想过滤该月所有星期的记录,然后计算平均值。注意: weekList 是当月的星期一列表。
(具有EventId = 1的记录数)/(具有EventId = 2或5的记录数和具有EventId = 1的empNum的记录数(创建日期为5天或更晚))
我所做的是:-
public class EventData
{
public int preEventId { get; set; }
public int empNum { get; set; }
public int EventId { get; set; }
public DateTime CreateDate { get; set; }
public string UserId { get; set; }
}
相同的示例sql结构:
int calledCount = lstEventData?.Where(e => e.EventId == 1 &&
e.CreateDate >= weekList.ToList()[week] &&
e.CreateDate <= weekList.ToList()[week].AddDays(4)).Count() ?? 0;
int totalCount = (lstEventData?
.Where(e => (e.EventCd == 2 || e.EventCd == 5) &&
e.CreateDate >= weekList.ToList()[week] &&
e.CreateDate <= weekList.ToList()[week].AddDays(4))
.GroupBy(e => e.empNum)
.Select(x => x.First())
.Count()) ?? 0;
int avgCalls = Convert.ToDecimal(calledCount) / Convert.ToDecimal(totalCount);
我如何实现我的实际目标?
解决方法
根据我从您的代码和解释中可以得出的结论,我认为这是您追求的目标:
// first,to reduce parsing your weekList EVERY time,get a reference to your start/end dates
var wkStart = weekList.ToList()[week];
// This may not quite work since if your weekstart is Monday midnight,// adding 4 days is Friday midnight,so 12:01 AM Friday won't fall into your range.
// I'd recommend doing AddDays(5),and using less than (<),not less than or equal (<=)
var wkEnd = wkStart.AddDays(5);
// using consts to avoid "magic numbers"
const int CALLED_LIST = 1;
const int OTHER_EVENTS = 2;
// Then get all of the events in that period that match the EventIds you want,// just so your followup queries are against a smaller set
var events =
lstEventData?
.Where(e => (
(e.EventId == 1 && e.CreateDate >= wkStart && e.CreateDate <= wkEnd) // event ID 1 within date range
|| e.EventId == 2 || e.EventId == 5 // or event ID 2 or 5,ingoring date range for the moment
))
// Create a lookup to split by event ID to have two separate lists to join below
.ToLookup(e => e.EventId == 1 ? CALLED_LIST : OTHER_EVENTS);
var calledList = events[CALLED_LIST].ToList();
var otherEvents = events[OTHER_EVENTS].ToList();
if ((calledList?.Count ?? 0) == 0)
{
// you need to handle empty or null to
// avoid a DivdeByZero error below.
return;
}
// by handling the null/empty above,you no longer need to handle it everywhere below;
var joinedResults =
calledList.Join(otherEvents,c => c.empNum,e => e.empNum,(c,e) => new {Parent = c,Child = e})
.Where(joined => joined.Parent.CreateDate > joined.Child.CreateDate.AddDays(-5));
// From here,you'll need to figure out what average you're trying to get.
// I made a note in the comments that I'm unclear what average you're trying to calculate.
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。