我有以下课程:
public class Item
{
public int Id { get; set; }
public string Sku { get; set; }
public List<Price> Prices { get; set; }
}
public class Price
{
public int Id { get; set; }
public double Cost { get; set; }
public PriceList List { get; set; }
}
public class PriceList
{
public int Id { get; set; }
public string FileName { get; set; }
public DateTime ImportDateTime { get; set; }
}
基本上,它是一个项目列表[Item
],其中每个项目都有一个价格列表[List<Price> Prices
](一对多),每个价格都有一个价目表[PriceList List
](一对一)。
我需要的是所有价目表的清单。
看起来我需要的是一个小组到一个&#34;孙子&#34;,基本上,按PriceList
&#39; Id
分组({{1} },而在列表中的Price
下面。)
因此,作为一个例子,如果我有五个价目表,它应该返回五行。
我做到了以下很长的路要走:
Item
如何使用LINQ实现?
更新
这是一个基本的样本集:
List<PriceList> priceLists = new List<PriceList>();
foreach (Item item in items)
{
foreach (Price price in item.Prices)
{
PriceList list = price.List;
if (!priceLists.Any(x => x.Id == list.Id))
{
priceLists.Add(list);
}
}
}
让我们从头到尾开始:
PriceList priceList1 = new PriceList { Id = 1, FileName = "Price List 1.csv" };
PriceList priceList2 = new PriceList { Id = 2, FileName = "Price List 2.csv" };
Price price1 = new Price { Id = 1, Cost = 2.65, List = priceList1 };
Price price2 = new Price { Id = 2, Cost = 14.23, List = priceList2 };
Price price3 = new Price { Id = 3, Cost = 29.01, List = priceList1 };
Price price4 = new Price { Id = 4, Cost = 1, List = priceList2 };
Price price5 = new Price { Id = 5, Cost = 56.12, List = priceList1 };
Item item1 = new Item { Id = 1, Sku = "item1", Prices = new List<Price> { price1, price2 } };
Item item2 = new Item { Id = 2, Sku = "item2", Prices = new List<Price> { price3, price4 } };
Item item3 = new Item { Id = 3, Sku = "item3", Prices = new List<Price> { price5 } };
List<Item> itemsList = new List<Item> { item1, item2, item3 };
(Item
)的列表,其中包含三个itemsList
。Item
都有一个Item
列表。Price
都有一个Price
。 澄清所有这些背后的原因:用户导入他们定期从供应商处获得的价格(价格表)电子表格,价格波动,每个价格表对同一商品的价格不同。因此,具有多个价格和每个价格的物品的原因有其用于上传它的价目表(PriceList
类中包含的更多信息,我省略了它以保持简单)。 / p>
我希望我能清楚。
答案 0 :(得分:1)
这似乎是你想要的,使用扩展来通过lambda表达式做区别:
var ans = itemsList.SelectMany(item => item.Prices.Select(price => price.List)).DistinctBy(price => price.Id);
扩展名如下:
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> src, Func<T, TKey> keyFun) {
var seenKeys = new HashSet<TKey>();
foreach (T e in src)
if (seenKeys.Add(keyFun(e)))
yield return e;
}
如果您改变了使用HashSet<Int>
来跟踪所见ID的方法,那么您可能会比LINQ更有效率。
答案 1 :(得分:0)
看起来您可以将SelectMany
(以获取所有Prices
列表)与Select
合并(以获取所有相关的PriceList
属性):
List<PriceList> priceLists = items.SelectMany(i => i.Prices).Select(p => p.List).ToList();
修改强>
以上内容将返回所有PriceLists
,但由于许多Items
可能引用相同的PriceList
,因此您需要一种方法来过滤PriceList.Id
字段。
执行此操作的一种方法是覆盖Equals
对象的GetHashCode
和PriceList
属性。如果您确实认为两个PriceList
对象具有相同的Id
,那么您可以执行以下操作:
public class PriceList
{
public int Id { get; set; }
public string FileName { get; set; }
public DateTime ImportDateTime { get; set; }
public override bool Equals(object obj)
{
var other = obj as PriceList;
return Id == other?.Id;
}
public override int GetHashCode()
{
return Id;
}
}
这允许您在价格上使用Linq
方法Distinct
(它会调用Equals
方法来区分结果中的PriceLists
:
List<PriceList> priceLists = items
.SelectMany(i => i.Prices)
.Select(i => i.List)
.Distinct()
.ToList();