我需要按时间顺序返回警报列表。下面的方法1做到了这一点。
我还需要获取某种警报类型的警报,以便如果AlertTypeID = {1,2,3,6,8,9,x},则通过CreateDate返回这些警报并按月进行排序。 下面的方法2就是这样做的。
现在,我需要将方法2的结果插入到方法1的结果中。 即使方法2返回的项目按月组织,我们也只是 关心最近的。只有方法2中最新的子组项需要遵循从方法1返回的项的时间顺序。此子组 item将确定子组2中其余每月项目的位置。
最后一项要求是必须删除重复项。如果正在退货 从子组警报中,它不能也存在于主组警报中。
下面我举例说明了我想要达到的效果:
december alert 1 (12/23/2012)
december alert 2 (12/21/2012)
december alert 3 (12/20/2012)
december subalert 1 (12/19/2012)
december subalert 2 (12/18/2012)
december subalert 3 (12/04/2012)
december subalert 4 (12/01/2012)
december alert 4 (12/18/2012)
december alert 5 (12/12/2012)
november alert 1 (11/22/2012)
november alert 2 (11/16/2012)
november subalert 1 (11/14/2012)
november subalert 2 (11/08/2012)
november alert 3 (11/12/2012)
代码:
所有提醒按日期时间
List<Alert> result = new List<Alert>();
using(NeuroLabLinqDataContext dc = conn.GetContext())
{
IEnumerable<Alert> alerts = (from a in dc.Alerts
where a.AccountID == AccountID
orderby a.CreateDate descending
select a).Take(40);
result = alerts.ToList();
}
return result;
按月提醒的警报类型
List<Alert> result = new List<Alert>();
int[] alertTypes = {1,2,3,4,5,6,7,8,9};
using (NeuroLabLinqDataContext dc = conn.GetContext())
{
IEnumerable<Alert> alerts = (from a in dc.Alerts
where a.AccountID == AccountID &&
alertTypes.Contains(a.AlertTypeID)
orderby ((DateTime)a.CreateDate).Month ascending
select a).ToList();
}
return result;
最终select语句的分组应如下所示:
select new { Date = alerts.CreateDate,
Message = alerts.Message,
Type = alert.AlertTypeID,
RecentActivity = [if from method 2, then true] };
更新:已更新方法
public List<Alert> GetAlertsByAccountID(Int32 AccountID, params int[] alertTypes)
{
List<Alert> result = new List<Alert>();
using (NeuroLabLinqDataContext dc = conn.GetContext())
{
var all = (from a in dc.Alerts
where a.AccountID == AccountID
orderby a.CreateDate descending
select a);
int abc = all.Count();
var first = all
.Where(a => a.AccountID == AccountID) && !alertTypes.Contains(a.AlertTypeID))
.OrderByDescending(a => a.CreateDate)
.GroupBy(a => a.CreateDate.Date)
.ToDictionary(g => g.Key);
var firstKeys = first.Keys.Cast<DateTime>()
.ToList().OrderBy(k => k);
var second = all
.Where(a => a.AccountID == AccountID) && alertTypes.Contains(a.AlertTypeID))
.OrderBy(a => a.CreateDate.Month)
.GroupBy(a => a.CreateDate.Month)
.ToDictionary(g => firstKeys
.First(k => k > g.OrderByDescending(a => a.CreateDate)
.FirstOrDefault().CreateDate));
var combined = first
.GroupJoin(
second,
fk => fk.Key,
sk => sk.Key,
(d, l) => d.Value
.Union(l.SelectMany(i => i.Value).ToArray()))
.SelectMany(i => i);
result = combined.ToList();
}
return result;
}
感谢约翰,我更进一步。目前,我收到以下错误:
序列不包含匹配元素
在这一行(我很确定):
.First(k => k > g.OrderByDescending(a => a.CreateDate)
对于它的价值,这里是我的警报表中的数据。
AlertID AccountID CreateDate Timestamp AlertTypeID Message
122 5 2008-03-11 20:48:07.983 0x00000000000128FB 9 sdfs
123 1 2008-03-11 20:48:39.957 0x00000000000128FE 8 sdfsd
124 5 2008-03-11 20:48:39.977 0x00000000000128FF 8 sdfs
125 5 2008-03-11 20:48:40.017 0x0000000000012901 8 asdfa
126 1 2008-03-12 22:57:42.160 0x00000000000130B3 4 sfsf
127 5 2008-03-12 22:57:42.337 0x00000000000130B4 4 sdfsd
128 5 2008-03-13 09:42:14.237 0x0000000000013889 4 sdfsd
129 5 2008-03-13 09:42:31.957 0x000000000001388B 4 sdfsd
130 5 2008-03-13 09:42:45.397 0x000000000001388D 5 asdfsdf
131 1 2008-03-16 14:52:17.197 0x0000000000014822 9 asdfsdf
132 1 2008-04-12 15:25:17.330 0x000000000001B582 3 sfasdf
133 5 2008-04-12 15:25:17.700 0x000000000001B583 3 dfsfds
134 6 2008-04-14 08:37:03.273 0x000000000001BD87 3 aasfsd
135 6 2008-04-14 08:37:15.270 0x000000000001BD89 3 fhfsdf
136 6 2008-04-14 08:38:45.120 0x000000000001BD8B 2 ghsdgd
137 6 2008-04-14 08:41:30.407 0x000000000001BD9A 4 fghsdfg
138 6 2008-04-14 08:42:30.800 0x000000000001BD9C 4 gfsdf
139 6 2008-04-14 08:42:43.763 0x000000000001BD9E 5 sdfsdf
140 6 2008-04-14 08:49:25.450 0x000000000001BDAA 9 sdfasdfa
141 6 2008-04-14 08:49:34.237 0x000000000001BDAC 9 sdfasdf
142 1 2008-04-14 08:50:23.380 0x000000000001BDAF 8 sdfhdfhsg
143 6 2008-04-14 08:50:23.567 0x000000000001BDB0 8 dgasdf
144 5 2008-04-14 08:50:23.690 0x000000000001BDB1 8 dgasdf
145 6 2008-04-14 08:50:23.747 0x000000000001BDB2 8 dgasdf
147 1 2008-06-24 14:22:41.183 0x00000000000222E6 14 dgasdf
148 5 2008-06-24 14:22:41.617 0x00000000000222E7 14 dgasdf
149 6 2008-06-24 14:22:41.623 0x00000000000222E8 14 dgasdf
150 1 2008-06-24 20:11:57.757 0x0000000000022AB3 13 dgasdf
151 5 2008-06-24 20:11:57.947 0x0000000000022AB4 13 dgasdf
152 6 2008-06-24 20:11:57.953 0x0000000000022AB5 13 dgasdf
153 1 2008-07-03 18:41:51.067 0x0000000000028888 14 dgasdf
154 5 2008-07-03 18:41:51.230 0x0000000000028889 14 dgasdf
155 6 2008-07-03 18:41:51.237 0x000000000002888A 14 dgasdf
156 1 2008-07-03 18:46:17.873 0x000000000002888D 14 dgasdf
157 5 2008-07-03 18:46:17.937 0x000000000002888E 14 dgasdf
158 6 2008-07-03 18:46:17.940 0x000000000002888F 14 dgasdf
答案 0 :(得分:3)
关键是将两个组分成字典,使用第一个列表中的日期作为字典的键,并在第二个列表项日期之后选择最接近的键作为第二个字典的键。
如果您有两个词典,每个词典都使用类型和子类型的公共键值,您只需执行GroupJoin
和SelectMany
即可将结果输入到排序列表中。
(*请注意,答案是基于稍微不同的早期版本的问题,我不会花时间更新答案,因为我认为已经在这个答案中说明和解决了基本问题)
更新2
我意识到你在First()调用中看到的问题是你的一些subalert项可能比任何其他警报项更新,这会导致你的异常。我通过使用DateTime::MaxValue
向第一个字典添加'代理'键来解决这个问题,然后我不再从第一个列表中过滤出子图,我只是在最终结果上使用.Distinct()
来删除重复项
使用linqpad我模拟了这个问题,并使用词典和GroupJoin
var all = new []{
new {date = DateTime.Parse("2012-12-23"), type = "alert", value = 1, accountId = 333 },
new {date = DateTime.Parse("2012-12-21"), type = "alert", value = 2, accountId = 333 },
new {date = DateTime.Parse("2012-12-20"), type = "alert", value = 3, accountId = 333 },
new {date = DateTime.Parse("2012-12-18"), type = "alert", value = 4, accountId = 333 },
new {date = DateTime.Parse("2012-12-12"), type = "alert", value = 5, accountId = 333 },
new {date = DateTime.Parse("2012-11-22"), type = "alert", value = 1, accountId = 333 },
new {date = DateTime.Parse("2012-11-16"), type = "alert", value = 2, accountId = 333 },
new {date = DateTime.Parse("2012-11-12"), type = "alert", value = 3, accountId = 333 },
new {date = DateTime.Parse("2012-12-19"), type = "subalert", value = 1, accountId = 333 },
new {date = DateTime.Parse("2012-12-18"), type = "subalert", value = 2, accountId = 333 },
new {date = DateTime.Parse("2012-12-04"), type = "subalert", value = 3, accountId = 333 },
new {date = DateTime.Parse("2012-12-01"), type = "subalert", value = 4, accountId = 333 },
new {date = DateTime.Parse("2012-11-14"), type = "subalert", value = 1, accountId = 333 },
new {date = DateTime.Parse("2012-11-08"), type = "subalert", value = 2, accountId = 333 },
/*add*/ new {date = DateTime.Parse("2012-12-25"), type = "subalert", value = 9, accountId = 333 },
};
var first = all
.Where(a=>a.accountId == 333 /* removed && type != "alert" */)
.OrderByDescending(a=>a.date)
.GroupBy(a=>a.date.Date)
.ToDictionary(g=>g.Key);
var firstKeys = first.Keys
.Cast<DateTime>()
.Union(new []{DateTime.MaxValue}) /* added this 'surrogate' key */
.OrderBy(k=>k)
.ToArray();
var second = all
.Where(a=>a.accountId == 333 && a.type == "subalert")
.OrderBy(a=>a.date.Month)
.GroupBy(a=>a.date.Month)
.ToDictionary(g=>firstKeys.First(k=>k > g.OrderByDescending(a=>a.date).FirstOrDefault().date));
var combined = first
.GroupJoin(
second,
fk=>fk.Key,
sk=>sk.Key,
(d,l)=>d.Value
.Union(l.SelectMany(i=>i.Value).ToArray()))
.SelectMany(i=>i)
.Distinct(); /* Added this to remove duplicates */
combined.Dump();
哪个收益率: