[英]LINQ for comparing two lists with complex entities
我們有一個下面列出的類結構
public class ItemDTO
{
public int ItemID { get; set; }
}
public class CostPageDTO
{
public string CostPageNumber { get; set; }
public List<ItemDTO> Items { get; set; }
}
有兩個列表– 1)數據庫中存在的成本頁和物料列表2)用戶選擇的成本頁
題
我們需要比較這兩個列表,並得到一個包含成本頁面的結果列表,這些成本頁面的實際集合和選定集合中的不同項目數相同。
為此(鏈式方法), best performing
LINQ是什么?
預期結果
在以下情況下,“預期結果”是一個僅包含1個成本頁的列表–“ C2”(匹配的項目)
碼
static void Main(string[] args)
{
List<CostPageDTO> selectedCostPageAndItems = GetSelectedCostPageAndItems();
List<CostPageDTO> actualItems = GetActualItems();
//LINQ code to get the matching count costPages
}
private static List<CostPageDTO> GetSelectedCostPageAndItems()
{
ItemDTO i1 = new ItemDTO();
i1.ItemID = 1;
ItemDTO i2 = new ItemDTO();
i2.ItemID = 2;
ItemDTO i3 = new ItemDTO();
i3.ItemID = 3;
CostPageDTO c1 = new CostPageDTO();
c1.CostPageNumber = "C1";
c1.Items = new List<ItemDTO>();
c1.Items.Add(i1);
CostPageDTO c2 = new CostPageDTO();
c2.CostPageNumber = "C2";
c2.Items = new List<ItemDTO>();
c2.Items.Add(i2);
c2.Items.Add(i3);
//CostPageDTO c2Duplicate = new CostPageDTO();
//c2Duplicate.CostPageNumber = "C2";
//c2Duplicate.Items = new List<ItemDTO>();
//c2Duplicate.Items.Add(i2);
//c2Duplicate.Items.Add(i3);
List<CostPageDTO> selectedCostPageAndItems = new List<CostPageDTO>();
selectedCostPageAndItems.Add(c1);
selectedCostPageAndItems.Add(c2);
//selectedCostPageAndItems.Add(c2Duplicate);
return selectedCostPageAndItems;
}
private static List<CostPageDTO> GetActualItems()
{
ItemDTO i1 = new ItemDTO();
i1.ItemID = 1;
ItemDTO i2 = new ItemDTO();
i2.ItemID = 2;
ItemDTO i3 = new ItemDTO();
i3.ItemID = 3;
ItemDTO i3Duplicate = new ItemDTO();
i3Duplicate.ItemID = 3;
CostPageDTO c1 = new CostPageDTO();
c1.CostPageNumber = "C1";
c1.Items = new List<ItemDTO>();
c1.Items.Add(i1);
c1.Items.Add(i2);
c1.Items.Add(i3);
CostPageDTO c2 = new CostPageDTO();
c2.CostPageNumber = "C2";
c2.Items = new List<ItemDTO>();
c2.Items.Add(i2);
c2.Items.Add(i3);
c2.Items.Add(i3Duplicate);
List<CostPageDTO> actualItems = new List<CostPageDTO>();
actualItems.Add(c1);
actualItems.Add(c2);
return actualItems;
}
這將選擇您的預期結果:
方法語法:
var result = selectedCostPageAndItems.SelectMany(scp => actualItems.Where(acp=>acp.CostPageNumber == scp.CostPageNumber),
(scp,acp)=> new {CostPageNumber = scp.CostPageNumber,
scpItems = new HashSet<int>(scp.Items.Select(x=>x.ItemID)),
acpItems = new HashSet<int>(acp.Items.Select(x=>x.ItemID))})
.Where(x => x.scpItems.SetEquals(x.acpItems))
.Select(x => x.CostPageNumber);
查詢理解語法:
var result = from cp1 in selectedCostPageAndItems
from cp2 in actualItems
let items1 = new HashSet<int>(cp1.Items.Select(x=>x.ItemID))
let items2 = new HashSet<int>(cp2.Items.Select(x=>x.ItemID))
where cp1.CostPageNumber == cp2.CostPageNumber
&& items1.SetEquals(items2)
select cp1.CostPageNumber;
說明:
查找具有相同CostPageNumber
所有選定對( scp
)和實際( acp
) CostPageDTO
對
selectedCostPageAndItems.SelectMany(scp => actualItems.Where(acp=>acp.CostPageNumber == scp.CostPageNumber)
對於每個這樣的對( scp
和acp
),選擇CostPageNumber
和一組ItemDTO.ItemID
選定( scpItems
)和實際( acpItems
) CostPageDTO
(scp,acp)=> new {CostPageNumber = scp.CostPageNumber,
scpItems = new HashSet<int>(scp.Items.Select(x=>x.ItemID)),
acpItems = new HashSet<int>(acp.Items.Select(x=>x.ItemID))})
最后選擇具有相同集合的CostPageNumber
Where(x => x.scpItems.SetEquals(x.acpItems)).Select(x => x.CostPageNumber)
HashSet
的創建和比較都是O(n)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.