ID Name from to
001-1 ABC 2015/05/01 2015/05/31
001-1 ABC 2015/06/01 2015/07/15
003-2 DEF 2015/05/01 2015/05/11
002-1 LMN 2015/05/01 2015/06/15
002-1 LMN 2015/06/16 2015/07/31
003-2 DEF 2015/06/01 2015/07/15
004-5 GHI 2015/05/11 2015/05/15
我想将记录合并到一个匹配2015/05/15
到2015/07/15
的句点的记录,就像datable中的以下结果一样。
ID Name from to
001-1 ABC 2015/05/01 2015/07/15
002-1 LMN 2015/05/01 2015/07/31
003-2
和004-5
不在新数据表中,因为它们不在require范围内。
我怎么能得到这个?我只知道关于LINQ的非常基本的知识,这对我来说非常新鲜。 THX。
答案 0 :(得分:0)
将此类/数据作为模型:
class Item
{
public string ID { get; set; }
public string Name { get; set; }
public DateTime From { get; set; }
public DateTime To { get; set; }
}
List<Item> items = new List<Item> {
new Item { ID = "001-1", Name = "ABC",
From = DateTime.Parse("2015/05/01"),
To = DateTime.Parse("2015/05/31") },
new Item { ID = "001-1", Name = "ABC",
From = DateTime.Parse("2015/06/01"),
To = DateTime.Parse("2015/07/15") },
new Item { ID = "003-2", Name = "DEF",
From = DateTime.Parse("2015/05/01"),
To = DateTime.Parse("2015/05/11") },
new Item { ID = "002-1", Name = "LMN",
From = DateTime.Parse("2015/05/01"),
To = DateTime.Parse("2015/06/15") },
new Item { ID = "002-1", Name = "LMN",
From = DateTime.Parse("2015/06/16"),
To = DateTime.Parse("2015/07/31") },
new Item { ID = "003-2", Name = "DEF",
From = DateTime.Parse("2015/06/01"),
To = DateTime.Parse("2015/07/15") },
new Item { ID = "004-5", Name = "GHI",
From = DateTime.Parse("2015/05/11"),
To = DateTime.Parse("2015/05/15") }
};
您可以使用以下linq查询来获取所需的结果集:
var result = from i in items
orderby i.From
group i by new { i.ID, i.Name } into iGroup
where iGroup.First().From <= DateTime.Parse("2015/05/15") &&
iGroup.Last().To >= DateTime.Parse("2015/07/1") &&
(iGroup.Last().To - iGroup.First().From).Days + 1 ==
iGroup.Sum(g => (g.To - g.From).Days + 1)
select new Item
{
ID = iGroup.Key.ID,
Name = iGroup.Key.Name,
From = iGroup.First().From,
To = iGroup.Last().To
};
您可以调整日期时间比较以适合您的实际需求。在上面的linq查询中,我将每个组的最小From
日期和最大To
日期与匹配的期间日期进行比较。
这个比较:
(iGroup.Last().To - iGroup.First().From).Days + 1 ==
iGroup.Sum(g => (g.To - g.From).Days + 1)
检查日期范围内没有间隙的组。
修改强>
如果源数据存储在DataTable
中,例如:
DataTable items = new DataTable();
items.Columns.Add("ID", typeof(string));
items.Columns.Add("Name", typeof(string));
items.Columns.Add("From", typeof(DateTime));
items.Columns.Add("To", typeof(DateTime));
然后linq查询变得有点复杂:
var q = from i in items.AsEnumerable()
orderby i.Field<DateTime>("From")
group i by new { ID = i.Field<string>("ID"), Name = i.Field<string>("Name") } into iGroup
where iGroup.First().Field<DateTime>("From") <= DateTime.Parse("2015/05/15") &&
iGroup.Last().Field<DateTime>("To") >= DateTime.Parse("2015/07/1") &&
(iGroup.Last().Field<DateTime>("To") - iGroup.First().Field<DateTime>("From")).Days + 1 ==
iGroup.Sum(g => (g.Field<DateTime>("To") - g.Field<DateTime>("From")).Days + 1)
select new
{
ID = iGroup.Key.ID,
Name = iGroup.Key.Name,
From = iGroup.First().Field<DateTime>("From"),
To = iGroup.Last().Field<DateTime>("To")
};
上述查询返回匿名类型的IEnumerable
。可以使用Reflection将其转换回DataTable
(例如,请参阅this帖子)。