Как сгладить список со множеством массивов внутри с помощью LINQ

Мне очень трудно это понять и с чего начать, поэтому я надеялся, что кто-то сможет указать правильное направление. У меня есть список (клиенты), внутри которого есть массивы/списки. В основном я хочу свести все результаты списка в плоскую версию, если список.

public class Customer : EntityBase
{
    public Phonenumber[]      PhoneNumbers            { get; set; }
    public Contact            BillToContact           { get; set; }
    public Terms              Terms                    { get; set; }
 }

 public class Contact
 {
    public Phonenumber[]        PhoneNumbers     { get; set; }
    public Address              Address          { get; set; }
    public Key                  Key              { get; set; }
    public string               CompanyName      { get; set; }
    public string               Email            { get; set; }
    public string               FirstName        { get; set; }
}

public class Phonenumber
{
    public string               Number            { get; set; }
    public int                  Key               { get; set; }
}

public class Terms
{
    public int      DueDays                       { get; set; }
    public int      DiscountDays                  { get; set; }
}


public class Address
{
    public string               Address1                    { get; set; }
    public string               Address2                    { get; set; }
    public string               City                        { get; set; }
    public string               Country                     { get; set; }
}

public abstract class EntityBase
{
    public Guid   Id          { get; set; }
    public string Status      { get; set; }
    public int    Rev         { get; set; }
} 

Я пробовал много подходов и просто продолжаю путаться. Поэтому, если кто-то может помочь или даже указать мне правильное направление, я был бы чрезвычайно благодарен. ниже приведен один из подходов, которые я пробовал.

public IEnumerable<Customer> Find (Func<Customer , bool> predicate) {

     foreach (var p in Customer.SelectMany(p => p)) {
             if(predicate(p)) {
             yield return p;
          }
       }
     }

Я десериализую строку jason в список, но затем хочу отобразить ее в сетке данных, но igGrid не поддерживает привязку к вложенным (сложным) свойствам. Поэтому мне нужно сгладить список, чтобы в списке не было подуровней.


person Jimbo Jones    schedule 20.01.2015    source источник
comment
Вам нужен список чего?   -  person SLaks    schedule 21.01.2015
comment
каков ваш вклад? у тебя уже есть плоскость IEnumerable<Customer>, что ты пытаешься сгладить?   -  person DLeh    schedule 21.01.2015
comment
Вы пытаетесь получить список всех телефонных номеров для всех клиентов? Это единственный массив, который я вижу.   -  person Will Eddins    schedule 21.01.2015
comment
У меня есть список «Клиент», внутри которого, например, есть номера телефонов, поэтому для этого примера у меня есть много номеров телефонов, и я бы хотел, чтобы они были на первом уровне.   -  person Jimbo Jones    schedule 21.01.2015
comment
Вы можете сделать это, но ваша проблема в том, что если цель является объектом, она будет иметь другую структуру для каждого экземпляра объекта. Звучит грязно. Было бы полезно, если бы вы объяснили, чего вы пытаетесь достичь, делая это. Вы не возражаете?   -  person BobRodes    schedule 21.01.2015
comment
Я десериализую строку jason в список, но затем хочу отобразить в сетке данных, но gGrid не поддерживает привязку к вложенным (сложным) свойствам. Поэтому мне нужно сгладить список, чтобы не было подуровней списка.   -  person Jimbo Jones    schedule 21.01.2015
comment
Если вы пытаетесь сгладить всю эту структуру, у вас возникнут проблемы со всеми различными столбцами, поскольку у вас есть как контактные телефоны, так и номера телефонов клиентов, которые будут сложены с разными именами столбцов. Запрос также будет довольно запутанным. Можете ли вы перепроектировать свой пользовательский интерфейс, чтобы использовать информацию более естественным образом или более четко указать, какие столбцы вы хотели бы сгладить?   -  person Steve Mitcham    schedule 21.01.2015


Ответы (2)


Из вашего вопроса совсем не ясно, какой результат вы на самом деле хотите. Вы просто хотите список всех телефонных номеров? Или вы хотите сохранить другую информацию Customer, чтобы получить несколько экземпляров информации Customer, каждый экземпляр с отдельным номером телефона?

Вы можете выполнить первое с чем-то вроде этого:

IEnumerable<Phonenumber> numbers =
    customers.SelectMany(
        customer => customer.PhoneNumbers
                            .Concat(BillToContact.PhoneNumbers));

Если вам нужны только числа Customer.PhoneNumbers, а не числа в объекте BillToContact, просто оставьте .Concat(BillToContact.PhoneNumbers) из вышеперечисленного.

Если вы хотите сохранить одно или несколько значений из исходного объекта Customer, вы можете сделать что-то вроде этого:

var numbers = customers.SelectMany(
    customer => customer.PhoneNumbers.Select(
        number => new
        {
            Number = number, 
            FirstName = customer.BillToContact.FirstName,
            Email = customer.BillToContact.Email
        }));

Приведенное выше сгенерирует перечисление объектов анонимного типа, каждый из которых имеет один номер телефона, а также соответствующие значения FirstName и Email из связанного объекта Contact. Конечно, вы можете смешивать и сочетать (например, использовать .Concat(...) для включения телефонных номеров из объекта BillToContact) и включать любых конкретных участников Customer или Contact, которых вы хотите.

person Peter Duniho    schedule 20.01.2015

Чтобы выбрать массив PhoneNumber из List<Customer>, используйте SelectMany:

List<Customer> customers = [data];
PhoneNumber phoneNumbers = customers.SelectMany(x=>x.PhoneNumbers).ToArray();
person smiech    schedule 20.01.2015