C# 一个列表的复杂合并<;客户类型>;变成另一个
我需要返回按时间顺序排列的警报列表。下面的方法1可以做到这一点 我还需要获取某个警报类型的警报,这样如果警报类型ID={1,2,3,6,8,9,x},则按CreateDate返回这些警报,并按月排序。 下面的方法2可以做到这一点 现在,我需要将方法2的结果插入到方法1的结果中。 虽然方法2返回的项目是按月组织的,但我们仅 关心最近的事情。只有来自方法2的最新子组项需要遵循从方法1返回的项的时间顺序。这个分组 项目将确定子组2的其余每月项目的放置位置 最后一个要求是必须删除重复项。如果某个项目正在被退回 从子组警报中,它不能也存在于主组警报中 以下是我试图达到的效果的说明:C# 一个列表的复杂合并<;客户类型>;变成另一个,c#,.net,linq,C#,.net,Linq,我需要返回按时间顺序排列的警报列表。下面的方法1可以做到这一点 我还需要获取某个警报类型的警报,这样如果警报类型ID={1,2,3,6,8,9,x},则按CreateDate返回这些警报,并按月排序。 下面的方法2可以做到这一点 现在,我需要将方法2的结果插入到方法1的结果中。 虽然方法2返回的项目是按月组织的,但我们仅 关心最近的事情。只有来自方法2的最新子组项需要遵循从方法1返回的项的时间顺序。这个分组 项目将确定子组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;
更新:更新方法
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;
}
值得一提的是,以下是我的警报表中的数据
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
关键是将这两个组分解为字典,使用第一个列表中的日期作为字典的键,并选择第二个列表项日期之后最近的键作为第二个字典的键 一旦有了这两个字典,每个字典都为类型和子类型使用了一个公共键值,您只需执行
GroupJoin
和SelectMany
即可在排序列表中获得结果
(*请注意,答案基于问题的一个稍有不同的早期版本,我不会花时间更新答案,因为我认为基本问题已经在这个答案中得到说明和解决)
更新2
我意识到您在第一个()调用中看到的问题是,您的一些子警报项可能比任何其他警报项都要新,这将导致您的异常。我通过使用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();
var all=new[]{
新建{date=DateTime.Parse(“2012-12-23”),type=“alert”,value=1,accountId=333},
新建{date=DateTime.Parse(“2012-12-21”),type=“alert”,value=2,accountId=333},
新的{date=DateTime.Parse(“2012-12-20”),type=“alert”,value=3,accountId=333},
新的{date=DateTime.Parse(“2012-12-18”),type=“alert”,value=4,accountId=333},
新建{date=DateTime.Parse(“2012-12-12”),type=“alert”,value=5,accountId=333},
新建{date=DateTime.Parse(“2012-11-22”),type=“alert”,value=1,accountId=333},
新的{date=DateTime.Parse(“2012-11-16”),type=“alert”,value=2,accountId=333},
新的{date=DateTime.Parse(“2012-11-12”),type=“alert”,value=3,accountId=333},
新的{date=DateTime.Parse(“2012-12-19”),type=“subalert”,value=1,accountId=333},
新的{date=DateTime.Parse(“2012-12-18”),type=“subalert”,value=2,accountId=333},
新的{date=DateTime.Parse(“2012-12-04”),type=“subalert”,value=3,accountId=333},
新的{date=DateTime.Parse(“2012-12-01”),type=“subalert”,value=4,accountId=333},
新的{date=DateTime.Parse(“2012-11-14”),type=“subalert”,value=1,accountId=333},
新的{date=DateTime.Parse(“2012-11-08”),type=“subalert”,value=2,accountId=333},
/*添加*/new{date=DateTime.Parse(“2012-12-25”),type=“subalert”,value=9,accountId=333},
};
var first=all
.Where(a=>a.accountId==333/*已删除&&type!=“警报”*/)
.OrderByDescending(a=>a.date)
.GroupBy(a=>a.date.date)
.ToDictionary(g=>g.Key);
var firstKeys=first.Keys
.Cast()
.Union(新[]{DateTime.MaxValue})/*添加了此“代理”键*/
.OrderBy(k=>k)
.ToArray();
var秒=全部
.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组合=第一
.GroupJoin(
第二
fk=>fk.Key,
sk=>sk.Key,
(d,l)=>d.值
.Union(l.SelectMany(i=>i.Value).ToArray())
.SelectMany(i=>i)
.Distinct();/*添加此选项以删除重复项*/
组合。Dump();
这将产生:
“按时间顺序分组”?你是说分组吗?似乎你需要按一个标准分组,并在结果分组中排序项目。这是什么标准?你好,Abatishchev。不,我是说按时间顺序。列表1和列表2必须按(日期时间)CreateDate排序。您的插图中的警报似乎没有按日期排序?还是12月警报2应该是2012年12月21日而不是2012年12月11日?@CodeSherpa我仍在为你的标准挣扎。。。是否希望根据当月最新警报的日期(从第二次查询开始)将每月第二次查询的所有警报插入第一次查询的结果中,并且不希望再次添加第一次查询中已存在的结果?我刚打字就头疼。谢谢你的努力,约翰!是的,对原问题的修改是因为有些人感到困惑。我想澄清一下。我在下面的一行得到了“Sequence contains no matching element”:“.ToDictionary(g=>firstKeys.First(k=>k>g.OrderByDescending(a=>a.CreateDate).FirstOrDefault().CreateDate));”我确信这与我的数据和你的代码有更多的关系,所以,我正在使用它。“我会跟进并再次感谢您。”约翰回答得非常好。。。我在做som
.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
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();