0

変更するアクセス権がない LINQ クエリによって生成された匿名オブジェクトのリストがあります。

オブジェクトには次のプロパティがあります。

OrderId, RepId, FirstName, LastName, Address

多くの場合、各「担当者」は複数の注文を出すため、OrderId だけが異なる行が多数あります。同じ担当者が複数の注文を出した場合、これらを新しい構造で 6 つのグループにまとめてバッチ処理する必要があります。

OrderId1, OrderId2, ..., OrderId6, RepId, FirstName, LastName, Address

しかし、担当者が 8 つの注文を出した場合、6 つのバッチと 2 つのバッチが存在することになります。そのため、新しいオブジェクトが常に同じ数のプロパティを持つとは限りません。

最初の結果セットを RepId でグループ化することから始めましたが、次にどこに行けばよいかわかりません。

これはLINQを使用して可能ですか?

4

2 に答える 2

1

出力にはスキーマが異なる匿名オブジェクトがあるため、事態は少し複雑になります。

理想的には、"OrderId1"、"OrderId2" などのプロパティではなく、注文にリストを使用するようにエンティティ クラスを設計する必要があります。これは拡張可能ではなく、エラーが発生しやすくなります。しかし、その特定の質問については、LINQ とExpandoObjectを組み合わせてこれを実現できます。

orders.GroupBy(order => order.RepId)
      .SelectMany(orderGroup => orderGroup.Select((order, i) => new  {
                           Order = order,
                           ReqId = orderGroup.Key,
                           SubGroupId = i / 6
                         }))
    .GroupBy(h => new {
      ReqId = h.ReqId,
      SubGroupId = h.SubGroupId,
      FirstName = h.Order.FirstName,
      LastName = h.Order.LastName,
      Address = h.Order.Address
    })
    .Select(orderWithRichInfo => {
       dynamic dynamicObject = new ExpandoObject();

       int i = 1;
       foreach(var o in orderWithRichInfo)
       {
         ((IDictionary<string, object>)dynamicObject).Add("OrderId" + i, o.Order.OrderId);
         i++;
       }

       ((IDictionary<string, object>)dynamicObject).Add("FirstName", orderWithRichInfo.Key.FirstName);
       ((IDictionary<string, object>)dynamicObject).Add("LastName", orderWithRichInfo.Key.LastName);
       ((IDictionary<string, object>)dynamicObject).Add("Address", orderWithRichInfo.Key.Address);
       return dynamicObject;
    });

それが役に立てば幸い。

于 2016-08-02T09:21:15.080 に答える
0

最初のオプション。

リストとして6つのOrderId-sを取得したい場合は、作成できます

class OrderBundle
{
    public int RepId { get; set; }
    public List<int> OrderIds { get; set; }
}

アイテムをグループ化する:

var orderBundels = orderList
   .GroupBy(m => m.RepId)
   .Select(g => new OrderBundle
   {
       RepId = g.Key,
       OrderIds = g.Select(m => m.OrderId).ToList()
   });

次に、それらをグループに分割します。

List<OrderBundle> dividedOrderBundels = new List<OrderBundle>();
foreach (OrderBundle orderBundle in orderBundels)
{
    int bundelCount = (int)Math.Ceiling(orderBundle.OrderIds.Count() / 6.0);
    for (int i = 0; i < bundelCount; i++)
    {
        OrderBundle divided = new OrderBundle
        {
            RepId = orderBundle.RepId,
            OrderIds = orderBundle.OrderIds.Skip(i * 6).Take(6).ToList()
        };
        dividedOrderBundels.Add(divided);
    }
}      

2 番目のオプション:

以下のようにモデルを作成しなくても同じ結果が得られます。

var result = orderList
    .GroupBy(m => m.RepId)
    .SelectMany(g => g.Select((m, i) => new
    {
        RepId = g.Key,
        FirstName = m.FirstName,
        LastName = m.LastName,
        Address = m.Address,
        OrderId = m.OrderId,
        BunleIndex = i / 6
    }))
    .GroupBy(m => m.BunleIndex)
    .Select(g => new
    {
        RepId = g.Select(m => m.RepId).First(),
        FirstName = g.Select(m => m.FirstName).First(),
        LastName = g.Select(m => m.LastName).First(),
        Address = g.Select(m => m.Address).First(),
        OrderIds = g.Select(m => m.OrderId).ToList()
    })
    .ToList()
于 2016-08-02T08:28:52.040 に答える