2017-10-03 3 views
0

Avec le code suivant, comment puis-je joindre des éléments ensemble.C# joindre des éléments qui sont les mêmes avec l'expression lambda

var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
    .Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId) 
    .Select(x => x.ShipmentItems) 
    .ToList(); 

Il peut donc y avoir deux envois ou plus pour l'ID de la commande. Chaque envoi peut contenir des articles identiques.

Besoin d'un petit coup de pouce dans la bonne direction

Ont essayé

var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
    .Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId) 
    .Select(x => x.ShipmentItems.Join(x.ShipmentItems 
     .Where(y => y.ShipmentId == shipment.Id))) 
    .ToList(); 

et

var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
    .Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId) 
    .Select(x => x.ShipmentItems.GroupBy(y => y.Id)) 
    .ToList(); 

et

var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
    .Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId) 
    .Select(x => x.ShipmentItems.Distinct()) 
    .ToList(); 

est le code J'utilise ici pour la sortie les articles:

foreach (var shipmentItem in shippedItems) 
{ 
    System.Diagnostics.Debug.WriteLine("item = " + shipmentItem); 
    System.Diagnostics.Debug.WriteLine("item = " + shipmentItem.OrderItemId); 
} 

La sortie ci-dessus produit:

nombre de shippedItemsList = 9 item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356077

item = System.Data.Entity. DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356078

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356079

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356077

item = System.Data.Entity.DynamicProxies. ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356078

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAA FA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356079

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356077

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356079

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356080

Ainsi, la sortie doit être exceptés:

nombre shippedItemsList = 4 item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356077

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356079

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356078

item = System.Data.Entity.DynamicProxies.ShipmentItem_18BEAAFA747B42988EC4CB25D967298CC6736AF528389FC98E81143F7D629631 item = 356080

ci-dessus la sortie est en utilisant var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId).SelectMany(x => x.ShipmentItems).ToList();

NOTE: l'article d'expédition est ICollection<ShipmentItem> Shipment.ShipmentItems quand je passe la souris dans visual studio

MISE À JOUR senario:

Alors disons que l'ordre a 3 points (a = 3, b = 5, c = 3), maintenant 1 expédition est envoyé avec les éléments (a = 1, b = 2, c = 0), Une deuxième expédition est maintenant envoyée avec les items (a = 1, b = 1, c = 1). Je voudrais la quantité d'articles des deux expéditions. Donc j'attends des items (a = 2, b = 3, c = 1), j'obtiens actuellement des items (a = 1, b = 2) + des items (a = 1, b = 1, c = 1). Ainsi, la liste des envois que j'emprunte traverse apparaissent plus d'une fois.

Je pensais que peut-être l'union, mais ne savez pas comment mettre ensemble:/

MISE À JOUR MON SOLUTION

je ne pouvais pas arriver à cette fin en utilisant l'expression lambda, donc je dû faire ce qui suit solution pour obtenir le résultat que je voulais. J'espère que cela aide les autres à la recherche de solutions de contournement.

//calculate quantity of total shipped items from each shipment 
      List<ShipmentItem> alreadyShippedItemsList = new List<ShipmentItem>(); 
      Dictionary<int, int> alreadyShippedItems = new Dictionary<int, int>(); 

      var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
      .Where(x => x.ShippedDateUtc != null) 
      .SelectMany(x => x.ShipmentItems) 
      .ToList(); 

      //create a list of shipment items 
      for (int i = 1; i <= shipmentsList.Count - 1; i++) 
      { 
       var si = shipmentsList[i]; 

       var sii = si.ShipmentItems.ToList(); 

       foreach (var item in sii) 
       { 
        var itemInList = alreadyShippedItemsList.Where(x => x.OrderItemId == item.OrderItemId).FirstOrDefault(); 
        int sum = 0; 

        //create a list of shipment items and check for duplicate items 
        if (itemInList == null) 
        { 
         alreadyShippedItems.Add(item.OrderItemId, item.Quantity); 
         alreadyShippedItemsList.Add(item); 
        } 
        else 
        { 
         //if duplicate item is found update the quantity in the dictionary 
         sum = itemInList.Quantity + item.Quantity; 
         alreadyShippedItems[item.OrderItemId] = sum; 
        } 
       } 
      } 
+0

Selon vos besoins, est-ce "Joindre", ou "Union". Perharp si vous pouvez fournir vos données, et votre sortie requise, il devrait être plus facile pour nous – Jacky

+0

@Jacky voir ma question mise à jour, ont ajouté la sortie requise. –

+0

@ Sujit.Warrier donc 1 commande peut avoir 3 expéditions, chaque expédition peut avoir n'importe quel nombre d'articles de la commande. –

Répondre

3

Vous devez utiliser SelectMany, qui aplatit un list

var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId) 
.SelectMany(x => x.ShipmentItems) 
.ToList(); 
+0

Cela ne fonctionne toujours pas comme prévu. Voir ma question mise à jour, avoir un exemple de sortie que je devrais obtenir. Merci d'aider :) –

+0

Cela semble être la bonne solution de mon googling. Mais la liste n'est pas aplatie, de sorte que le même élément apparaît plus d'une fois dans la liste. :( –

+0

Peut-être que vous devez appliquer un '.Where' à' ShippingItems'? –

1

Vous utilisez Distinct au mauvais endroit

var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId) 
.Select(x => x.ShipmentItems).Distinct() 
.ToList(); 

Soit surchargent equals fonction de la classe ShipmentItems utilisant ce Correct way to override Equals() and GetHashCode() et utiliser distinct directement ou faire deux étapes

var distinctShippedItemIds = _orderService.GetOrderById(shipment.OrderId).Shipments 
.Where(x => x.ShippedDateUtc != null && x.OrderId == shipment.OrderId) 
.Select(x => x.ShipmentItems.OrderItemId).Distinct() 
.ToList(); 

List<ShippingItems> UniqueItemList=new List<ShippingItems>(); 
foreach(int OrderId in distinctShippedItemIds) 
{ 
    var shippedItems = _orderService.GetOrderById(shipment.OrderId).Shipments 
.Where(x => x.ShippedDateUtc != null && x.OrderId == OrderId) 
.Select(x => x.ShipmentItems).FirstOrDefault(); 
     if(shippedItems !=null) 
     { 
     UniqueItemList.Add(shippedItems); 
     } 
} 
+0

Cela ne fonctionne pas encore. :( Encore même problème –

+0

damn je pensais que ShipmentItems était une propriété Int –

+0

Distinct ne fonctionne pas parce que, runtime doesnt sachez ce qui fait que deux bordereaux d'expédition sont égaux, vous devrez remplacer les equals() et gethashcodemethod() de votre classe ShipmentItems pour donner ces informations à l'exécution utilisez ce lien https://stackoverflow.com/questions/9317582/correct-way-to -override-equals-and-gethashcode –

1

Je peux me tromper mais est-ce que c'est ce que vous voulez?

SELECT * FROM [ShipmentItem] 
INNER JOIN [Shipment] ON [ShipmentItem].[ShipmentId] = [Shipment].[Id] 
WHERE [Shipment].[ShippedDateUtc] IS NOT NULL AND [Shipment].[OrderId] = @OrderId 

Donc cela va faire le travail

var shippedItems = _orderService.GetOrderById(orderId) 
     .Shipments 
     .Where(s => s.ShippedDateUtc != null) 
     .SelectMany(s => s.ShipmentItems) 
     .ToList(); 

Exemple ShipmentItems at database ShipmentItems at VS

Modifier

Si vous vous voulez chercher les éléments de commande que vous avez à faire quelque chose comme ça

var orderItems = _orderService 
    .GetOrderById(orderId) 
    .Shipments 
    .Where(s => s.ShippedDateUtc != null) 
    .SelectMany(s => s.ShipmentItems) 
    .Select(si => _orderService.GetOrderItemById(si.OrderItemId)) 
    .Distinct() 
    .ToList(); 

ou si vous voulez produit moins DB interroge

var orderItems = _orderService 
    .GetOrderById(orderId) 
    .Shipments 
    .Where(s => s.ShippedDateUtc != null) 
    .SelectMany(s => s.ShipmentItems) 
    .Select(si => si.OrderItemId) 
    .Distinct() 
    .Select(id => _orderService.GetOrderItemById(id)) 
    .ToList(); 

Edit 2

données NopCommerce d'une commande avec 4 éléments de commande (quantité de 2) et 4 envois DB Structure

+0

Le second bit du code d'expression lambda de code ne fonctionne pas. Donc disons que la commande a 3 items (a = 3, b = 5, c = 3), Maintenant 1 envoi est envoyé avec des items (a = 1, b = 2, c = 0), maintenant une deuxième expédition est envoyée avec des items (a = 1, b = 1, c = 1). Je voudrais la quantité d'articles des deux expéditions. Donc j'attends des items (a = 2, b = 3, c = 1), j'obtiens actuellement des items (a = 1, b = 2) + des items (a = 1, b = 1, c = 1). Ainsi, la liste des envois que j'emprunte traverse apparaissent plus d'une fois. J'espère que cela a du sens.Merci d'avoir aidé –

+0

Pour obtenir les quantités des deux expéditions, vous devez grouper ShipmentItems par OrderItemId et compter la quantité ensemble – Raphael

+0

Voir ma question mise à jour pour la solution qui a fonctionné pour moi, pour une raison quelconque, votre solution ne fonctionnerait pas pour moi. Merci quand même pour vôtre aide :) –