Запрос контейнера с группой Linq +?

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

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 и присоединиться к первой записи маршрутов каждого равного 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       GUIDpublic List<Waypoint> Routes = new List<Waypoint>();Routes
   6        55       GUID
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
Routes 7 55 GUID
Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1    100        0       10      129.32  437.21  29.10
Routes 8 55 GUID
Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1   1200        0       100     1029.32 837.21  29.10
Routes 9 1 GUID
Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1    100        0       10      129.32  437.21  29.10
Routes 10 1 GUID
        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;
                }
        }
Routes

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

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

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

GUID

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>();
}
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

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);
Routes имеют:

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

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

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

ItemID, Имя, ListOfRoutes

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

GUID

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>();
}
Routes первая запись:

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

Первая запись GUID

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);
Routes:

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

GUIDpublic List<ItemList> myList = new List<ItemList>();Routes, GUID

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       GUIDpublic List<Waypoint> Routes = new List<Waypoint>();Routes
   6        55       GUID
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
Routes 7 55 GUID
Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1    100        0       10      129.32  437.21  29.10
Routes 8 55 GUID
Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1   1200        0       100     1029.32 837.21  29.10
Routes 9 1 GUID
Entry   Zone    SubID   Heading     PosX    PosY    PosZ
    1    100        0       10      129.32  437.21  29.10
Routes 10 1 GUID
        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;
                }
        }
Routes
Routes, GUIDpublic List<Waypoint> Routes = new List<Waypoint>();Routes первые записи.

ОБНОВЛЕНИЕ 2:

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

        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;
                }
        }

person Prix    schedule 01.01.2011    source источник


Ответы (2)


Итак, то, что вы ищете, - это вариант того, что у меня было в первом запросе. Я все еще не уверен на 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
            };

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

person Jeff Mercado    schedule 01.01.2011
comment
Прежде всего, счастливого нового года и спасибо за ответ, я попробую, чтобы объяснить больше каждого элемента в public List<ItemList> myList = new List<ItemList>();, который имеет класс внутри списка маршрутов public List<Waypoint> Routes = new List<Waypoint>();, но некоторые элементы имеют более 1 маршрута, и мне нужна именно первая запись каждого пункт. - person Prix; 01.01.2011
comment
@Prim: Мне кажется, что первый запрос - это то, что вы ищете. - person Jeff Mercado; 01.01.2011
comment
@Jeff M, к сожалению, я не могу применить вышеизложенное на практике в текущем классе, который у меня есть, и в результирующем запросе мне также нужен - person Prix; 01.01.2011
comment
@Prix: Ой, я только что понял, что ошибся в вашем имени. Извиняюсь. :) Не могли бы вы привести более полный пример некоторых входных данных и того, что вы ожидаете? Что-то в виде примеров, которые я показал, было бы очень полезно для описания того, что вы пытаетесь сделать. - person Jeff Mercado; 01.01.2011
comment
@Jeff M еще раз спасибо, я обновил вопрос, надеюсь, обновление понятно. - person Prix; 01.01.2011
comment
@Jeff M еще раз спасибо за обновление, В конце вопроса я обновил его рабочим запросом, который я смог сделать, но я все еще верю, что есть лучший способ, и чтобы он мог уместиться в 1 запрос. - person Prix; 01.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 вообще не является списком.

person Amy B    schedule 01.01.2011
comment
Спасибо за ответ и с Новым годом вас;), я попробую ваш запрос через несколько. Что касается GUID, это потому, что когда я группирую его по ItemID, нет необходимости проверять GUID, но вы можете видеть, что у каждого GUID есть список маршрутов, и из этого списка маршрутов мне нужен только первый элемент. Итак, если ItemID 20 имеет 5 записей GUID, значит, у меня будет список маршрутов с 5 элементами, который является первым элементом каждого GUID, содержащего ItemID. - person Prix; 01.01.2011