Поворот списка IEnumerable - PullRequest
       10

Поворот списка IEnumerable

2 голосов
/ 20 февраля 2012

Я пытаюсь применить небольшую групповую / перекрестную логику к списку IEnumerable определенного пользователем объекта, и мне было интересно, может ли кто-нибудь помочь мне. Я застрял с существующей (довольно раздражающей) объектной моделью для работы, но в любом случае здесь идет ...

рассмотрим следующий класс, который я сконцентрирую только на соответствующих свойствах, чтобы вы получили jist ...

public class Holding
{
   private void Institution;
   private string Designation;
   private Owner Owner;
   private Event Event;
   private Shares Shares;
}

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

  • Объект сгруппирован по Учреждению.
  • Этот родительский список учреждений содержит список нового объекта с уникальной комбинацией Обозначение и Владелец.
  • Теперь для каждой из этих комбинаций Обозначение и Владелец мы получаем еще один дочерний список уникальных событий.

Так что это в основном 3 списка.

Я не уверен, возможно ли это с помощью IEnumerable List или нет, я довольно долго играл с методом расширения GroupBy, но пока безрезультатно. Я хотел бы, чтобы большинство делало это таким образом, но я использую linq-to-sql, чтобы получить первоначальный список владений, который выглядит следующим образом и может быть лучшим местом для ведения бизнеса ...

public static List<Holding> GetHoldingsByEvents(
    int eventId1,
    int eventId2)
{
    DataClassesDataContext db = new DataClassesDataContext();

    var q = from h in db.Holdings
             where
               h.EventId == eventId1 ||
               h.EventId == eventId2
             select h;

    return q.Distinct().ToList();
}

Любая помощь / руководство будет высоко ценится ...

Заранее спасибо.

1 Ответ

2 голосов
/ 21 февраля 2012

Я использую метод ToLookup, который является своего рода группировкой, он принимает два параметра, первый - функцию, используемую для определения групповых ключей, а следующий - функцию, используемую в качестве селектора (что взять из соответствия ).

items.ToLookup(c=>c.Institution.InstitutionId, c => new {c.Designation, c.Owner, c.Event})
    .Select(c => new {
        // find the institution using the original Holding list
        Institution = items.First(i=>i.Institution.InstitutionId == c.Key).Institution,
        // create a new property which will hold the groupings by Designation and Onwner
        DesignationOwner = 
                // group (Designation, Owner, Event) of each Institution by Designation and Owner; Select Event as the grouping result
                c.ToLookup(_do => new {_do.Designation, _do.Owner.OwnerId}, _do => _do.Event)
                            .Select(e => new {
                                // create a new Property Designation, from e.Key
                                Designation = e.Key.Designation,
                                // find the Owner from the upper group ( you can use items as well, just be carreful this is about object and will get the first match in list)
                                Owner = c.First(o => o.Owner.OwnerId == e.Key.OwnerId).Owner,
                                // select the grouped events // want Distinct? call Distinct
                                Events = e.Select(ev=>ev)//.Distinct()
                            })
    })




Я предположил, что ваши классы выглядят так

public class Holding
{
   public Institution Institution {get; set;}
   public string Designation {get; set;}
   public Owner Owner {get; set;}
   public Event Event {get; set;}   
}
public class Owner 
{
  public int OwnerId {get; set;}
}

public class Event 
{
  public int EventId {get; set;}
}

public class Institution 
{
  public int InstitutionId {get; set;}
}
...