#c# #linq #ienumerable
#c# #linq #ienumerable
Вопрос:
У меня могло бы быть несколько (до 5) IEnumerable<ResortSupplier>
и я хотел бы объединить их в одну IEnumerable<ResortSupplier>
группировку по коду поставщика. Мои объекты выглядят следующим образом:
Вот мои объекты:
[Serializable]
public class ResortSupplier
{
public string SupplierCode { get; set; }
public IList<Product> ResortProducts { get; set; }
}
[Serializable]
public class Product
{
public string Code { get; set; }
//Other fields...
public IList<PerPricing> PricingDetail { get; set; }
}
[Serializable]
public class PerPricing
{
//Other fields..
public decimal? Price { get; set; }
public Error PricingError { get; set; }
}
Данные в нескольких IEnumerable могут выглядеть следующим образом:
----------------------------------------
IEnumerable<ResortSupplier> - 1
Hyatt Resort
Standard Room
PricingDetail-1
Superior Room
PricingDetail-1
Sandals Resort
Standard Room
PricingDetail-1
Delux Room
PricingDetail-1
----------------------------------------
IEnumerable<ResortSupplier> - 2
Hyatt Resort
Standard Room
PricingDetail-2
Superior Room
PricingDetail-2
One Bed Room Suit
PricingDetail-2
Sandals Resort
Standard Room
PricingDetail-2
Honeymoon Suit
PricingDetail-2
----------------------------------------
IEnumerable<ResortSupplier> - 3
.....
----------------------------------------
IEnumerable<ResortSupplier> - 4
.....
----------------------------------------
IEnumerable<ResortSupplier> - 5
.....
----------------------------------------
Мой консолидированный результат должен содержать:
IEnumerable<ResortSupplier> - Consolidated
Hyatt Resort
Standard Room
PricingDetail-1
PricingDetail-2
Superior Room
PricingDetail-1
PricingDetail-2
Bed Room Suit
PricingDetail-2
Sandals Resort
Standard Room
PricingDetail-1
PricingDetail-2
Delux Room
PricingDetail-1
Honeymoon Suit
PricingDetail-2
----------------------------------------
Каков наилучший способ справиться с этим? Я попробовал простой IEnumerable.Предложения Union и GroupBy, но не дают мне желаемых результатов.
Комментарии:
1. К вашему сведению, объединение удалит дубликаты.
Ответ №1:
Если я вас правильно понимаю, вы должны использовать Concat, чтобы собрать их в одну большую коллекцию, затем вы можете группировать, как хотите
IEnumerable<ResortSupplier> master =
result1.Concat(result2).Concat(result3); //etc
Затем сгруппируйте, как обычно:
var resultGrouped = master.GroupBy(rs => rs.SupplierCode);
Комментарии:
1. Адам, пожалуйста. смотрите мои комментарии к сообщению Мартиньо.
2. Я думаю, что ваш вопрос сформулирован неправильно. Вызов concat для ваших 5 коллекций сведет их в одну. Группировка этой огромной коллекции будет … группировать it…by все, что вы укажете. Чего именно вы ожидаете и что происходит?
3. Адам, возможно, я не очень четко сформулировал свой вопрос, но мой пример показывает, какими должны быть мои ожидаемые результаты. Прошу прощения за путаницу. Решение Ani сработало для меня. Спасибо.
Ответ №2:
Я думаю, вы хотите что-то вроде:
// You can construct this with an array if it isn't already in this form.
IEnumerable<IEnumerable<ResortSupplier>> supplierLists = ...
var query = from suppliers in supplierLists
from supplier in suppliers
group supplier by supplier.SupplierCode into g
let products = g.SelectMany(s => s.ResortProducts)
.GroupBy(p => p.Code)
.Select(prodGroup => new Product
{
Code = prodGroup.Key,
PricingDetail = prodGroup
.SelectMany(p => p.PricingDetail)
.ToList()
})
select new ResortSupplier
{
SupplierCode = g.Key,
ResortProducts = products.ToList()
};
Хотя это действительно ужасно выглядящий запрос. Я настоятельно рекомендую разложить различные компоненты запроса на отдельные методы (с правильными именами).
Комментарии:
1. Ани, я мог бы получить несколько,
IEnumerable<ResortSupplier>
но неIEnumerable<IEnumerable<ResortSupplier>>
. Вы хотите, чтобы я сначала собралIEnumerable<IEnumerable<ResortSupplier>>
из всехIEnumerable<ResortSupplier>
?2. @Alex: Да. Например:
var supplierLists = new[] { supplierList1, supplierList2, ... };
3. Ани, это сработало. Спасибо. У меня также есть поле «LowestPrice» в
ResortSupplier
, которое будет содержать самую низкую цену из всех p.PricingDetail. Как я могу заполнить это поле? Я думаю, что мне, возможно, придется использовать.Min(p => p.Price)
функцию LINQ, но мне сложно создать запрос.4. Я получил самую низкую цену
SelectMany(p => p.PricingDetail).Min(p => p.Price)
, НО я хочу самую низкую ненулевую цену, если я использую предложение where, такое как.Where(l => l.Price > 0).Min(p => p.Price)
, оно удаляет элементы с нулевой ценой, предложение where действует как фильтр и удаляет ненулевые записи. Я хочу сохранить все записи нетронутыми, а также получить самую низкую ненулевую цену.