Запросить контейнер с Linq + group by? - PullRequest
1 голос
/ 01 января 2011

У меня есть этот класс:

public class ItemList
{
    public int GuID { get; set; }
    public int ItemID { get; set; }
    public string Name { get; set; }
    public entityType Status { get; set; }
    public int Zone { get; set; }

    public class Waypoint
    {
        public int SubID { get; set; }
        public int Heading { get; set; }
        public float PosX { get; set; }
        public float PosY { get; set; }
        public float PosZ { get; set; }
    }
    public List<Waypoint> Routes = new List<Waypoint>();
}

Что используется в этом списке: public List myList = new List ();

Новые элементы добавляются в это как:

ItemList newItem = new ItemList();
newItem.GUID = GUID;
newItem.ItemID = ItemID;
newItem.Name = Name;
newItem.Status = Status;

// Inner Routes List
ItemList.Waypoint itemLocation = new ItemList.Waypoint();
itemLocation.SubID = SubID;
itemLocation.Zone = Zone;
itemLocation.Heading = convertHeading(Heading);
itemLocation.PosX = PosX;
itemLocation.PosY = PosY;
itemLocation.PosZ = PosZ;
itemLocation.Rest = Rest;
newItem.Routes.Add(itemLocation);
myList.Add(newItem);

Теперь мне нужно сгруппировать его по ItemID и присоединиться к первой записи Routes каждого идентичного ItemID.

Это будет пример public List<ItemList> myList = new List<ItemList>(); данных:

GUID    ItemID      ListOfRoutes
   1        20       GUID_1_Routes
   2        20       GUID_2_Routes
   3        20       GUID_3_Routes
   4        20       GUID_4_Routes
   5        20       GUID_5_Routes
   6        55       GUID_6_Routes
   7        55       GUID_7_Routes
   8        55       GUID_8_Routes
   9         1       GUID_9_Routes
  10         1      GUID_10_Routes

Как видите, GUID уникален, ItemID может его повторить самостоятельно. Каждый GUID имеет список маршрутов, а список всех маршрутов имеет минимум 1 запись и более.

Маршруты являются частью класса ItemList public List<Waypoint> Routes = new List<Waypoint>();

Пример маршрута.

GUID_1_Routes имеет:

Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1   1200        0       100     1029.32 837.21  29.10
    2   1200        0       120     1129.32 537.21  29.10
    3   1200        0       180     1229.32 137.21  29.10
    4   1200        0       360     1329.32 437.21  29.10
    5   1200        0       100     1429.32 637.21  29.10

GUID_2_Routes имеет:

Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1    100        0       10      129.32  437.21  29.10

Итак, что я хочу сделать, это список всех записей, которые у меня есть в myList, сгруппированных по ItemID с сохранением полей ItemID и Name ... и новый список для ItemID, который будет хранить первый элемент каждого маршрута из каждого GUID, который имел тот же ItemID.

Например, ItemID 20 даст следующий результат:

ItemID, Name, ListOfRoutes

Этот ItemID ListOfRoutes будет содержать

GUID_1_Routes первая запись:

Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1   1200        0       100     1029.32 837.21  29.10

GUID_2_Routes первая запись:

Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1    100        0       10      129.32  437.21  29.10

GUID_3_Routes, GUID_4_Routes, GUID_5_Routes первые записи.

UPDATE2:

Вот как мне удалось получить желаемые результаты, но я все еще верю, что это было бы возможно с помощью одного запроса или лучше, чем то, что я сейчас использую:

        var query = from ItemList item in myList
                    where status.Contains(item.Status)
                    group item by new
                    {
                        item.ItemID,
                        item.Name,
                        item.Zone
                    }
                    into newList
                    orderby newList.Key.ItemID ascending
                    select new
                    {
                        newList.Key.ItemID,
                        newList.Key.Name,
                        newList.Key.Zone
                    };

        foreach (var thisItem in query)
        {
                var location = from n in myList
                               where n.ItemID == thisItem.ItemID
                               select new
                               {
                                   Routes = n.Routes.First()
                               };
                foreach (var thisObject in location)
                {
                    ItemList.Waypoint thisRoutes = thisObject.Routes;
                }
        }

Ответы [ 2 ]

2 голосов
/ 01 января 2011
  • В своем вопросе вы говорите: «из каждого GUID, который имел тот же ItemID.»
  • В вашем рабочем коде вы вообще не используете GUID.

-

  • В своем вопросе вы не упоминаете фильтрацию статуса.
  • В вашем рабочем коде есть фильтрация статуса.

-

В любом случае, я свел «рабочий код» к нескольким строкам.

from ItemList item in myList
where status.Contains(item.status)
group item by item.ItemID into groupedItems
order by groupedItems.Key descending
let firstItem = groupedItems.First()
let routes =
  from item2 in groupedItems
  select item2.Routes.First()
from route in routes
select new
{
  TheItemList = firstItem,
  TheWayPoint = route
};

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

Вам также следует лучше сообщить, что определяет каждый ключ, почему существуютдля начала повторяющиеся идентификаторы элементов в списке и почему класс с именем ItemList вообще не является списком.

2 голосов
/ 01 января 2011

Итак, вы ищете вариант того, что я имел в первом запросе. Я все еще не уверен на 100%, что понял ваше объяснение, но, основываясь на ваших результатах, я считаю, что это больше из того, что вы пытались сделать.

var query = from entry in myList
            where status.Contains(entry.Status)
            group entry.Routes.First() // take the first item in each route
                by new // assuming each id has a unique name
                {
                    entry.ItemID,
                    entry.Name
                }
                into g
            select new
            {
                g.Key.ItemID,
                g.Key.Name,
                ListOfRoutes = g.ToList() // return the grouping as list
            };

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...