如何使用LINQ将共享一个属性的两个列表合并为第三个列表
本文关键字:列表 三个 两个 合并 一个 LINQ 何使用 共享 属性 | 更新日期: 2023-09-27 17:50:43
我想创建以下类的列表(list(:
public class StatusData
{
public DateTime? Date { get; set; }
public int RegisteredUsers { get; set; }
public int Orders { get; set; }
public decimal Import { get; set; }
}
该列表应填充另外两个列表的信息:List<Contact>
和List<Purchase>
。两个类都有以下形状:
public class Contact
{
public DateTime? RegisterDate { get; set; }
public string Name { get; set; }
}
public class Purchase
{
public DateTime? PurchaseDate { get; set; }
public int PurchaseID {get;set;}
public int Import { get; set; }
}
这个想法是,列表应该每天显示注册用户的数量、购买量和这些购买的总进口量。所以,从本质上讲,两者只是共享日期。
但是,我无法提供一个好的LINQ表达式来创建List。我考虑的一个解决方案是检索2个列表中所有不同的日期,然后对它们进行迭代以检索我想要的信息,但我认为这种方法相当"丑陋"。有什么方法可以轻松地做我想做的事吗?
编辑:我想要的例子如下:
Contacts
--------
Name RegisteredDate
David 10/10/2013
Paul 09/10/2013
Gina 10/10/2013
Roger 09/10/2013
Rose 05/10/2013
Jean 07/10/2013
Mark 04/10/2013
Lisa 04/10/2013
Purchases
-----------
ID PurchaseDate Import
1 10/10/2013 10
2 10/10/2013 10
3 10/10/2013 20
4 04/10/2013 15
5 04/10/2013 15
6 07/10/2013 20
7 07/10/2013 2
8 07/10/2013 2
Expected result
----------------
Date RegisteredUsers Purchases Import
04/10/2013 2 2 30
05/10/2013 1 0 0
07/10/2013 1 3 24
09/10/2013 2 0 0
10/10/2013 2 3 40
亲切问候
var contacts = new List<Contact>();
var purchases = new List<Purchase>();
var dates = contacts.Select(x => x.RegisterDate.Value)
.Concat(purchases.Select(x => x.PurchaseDate.Value))
.Distinct();
var data = from date in dates
join c in contacts on date equals c.RegisterDate.Value into registered
join p in purchases on date equals p.PurchaseDate.Value into purchased
select new StatusData {
Date = date,
RegisteredUsers = registered.Count(),
Orders = purchases.Count(),
Import = purchases.Sum(x => x.Import)
};
当至少进行了一次注册或一次购买时,它将返回所有天的StatusData
。
所以这里有几个单独的任务。您要做的第一件事是按注册日期对联系人进行分组。接下来,您将根据日期将结果加入到Purchases表中,聚合两个不同列上的计数/总和。LINQ对这两种操作都有一种方法:
var query = from contact in contacts
group contact by contact.RegisterDate into contactGroup
join purchase in purchases
on contactGroup.Key equals purchase.PurchaseDate into purchaseGroup
select new StatusData
{
Date = contactGroup.Key,
RegisteredUsers = contactGroup.Count(),
Orders = purchaseGroup.Count(),
Import = purchaseGroup.Sum(p => p.Import),
};
这实际上是两个单独的查询,它们的结果在最后合并。
var contact = from c in Contact
group c by c.RegisterDate into c
select new StatusData
{
Date = c.Key,
RegisteredUsers = c.Count(),
Orders = 0,
Import = 0,
};
var purchases = from p in Purchases
group p by p.PurchaseDate into p
select new StatusData
{
Date = p.Key,
RegisteredUsers = 0,
Orders = p.Count(),
Import = p.Sum(x => x.Import),
};
var final = from x in contact.Concat(purchases)
group x by x.Date into x
select new StatusData
{
Date = x.Key,
RegisteredUsers = x.Sum(y => y.RegisteredUsers),
Orders = x.Sum(y => y.Orders),
Import = x.Sum(y => y.Import),
};