2013-08-02 2 views
3

J'ai une liste qui a des doublons.Comment puis-je choisir un enregistrement plutôt qu'un autre?

Row# Lineid ItemDescItemId RoadTax VehicleId Amount 
1 122317 None -1 26.63 -78603 300 
2 122317 None -2 17.75 -78603 200 
3 122317 None -1 22.19 -78602 250 
4 122317 Deli -2 17.75 -78603 200 

Dans ce cas, la ligne 2 est un double de rang 4, depuis le LineID, RoadTax, Montant et match de VehicleID. Cependant, je veux garder la ligne avec une description et d'éliminer la ligne # 2. Donc, ma liste de sortie ressemble à ceci:

Row# Lineid ItemDesc ItemId RoadTax VehicleId Amount 
1 122317 None -1 26.63 -78603 300 
3 122317 None -1 22.19 -78602 250 
4 122317 Deli -2 17.75 -78603 200 

j'ai écrit une classe IEqualityComparer basée sur un exemple sur MSDN. La classe ressemble à ceci:

public class RoadTaxComparer : IEqualityComparer<RoadTaxDto> 
     { 
      // Items are equal if ItemId/VehicleId/RoadTax are equal. 
      public bool Equals(RoadTaxDto x, RoadTaxDto y) 
      { 

       //Check whether the compared objects reference the same data. 
       if (Object.ReferenceEquals(x, y)) return true; 

       //Check whether any of the compared objects is null. 
       if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) 
        return false; 

       //Check whether the products' properties are equal. 
       return x.VehicleId == y.VehicleId && x.ItemId == y.ItemId && x.RoadTax == y.RoadTax && x.Amount == y.Amount; 
      } 

      // If Equals() returns true for a pair of objects 
      // then GetHashCode() must return the same value for these objects. 

      public int GetHashCode(RoadTaxDto roadTaxDto) 
      { 
       //Check whether the object is null 
       if (Object.ReferenceEquals(roadTaxDto, null)) return 0; 

       //Get hash code for the VehicleId. 
       int hashVehicleId = roadTaxDto.VehicleId.GetHashCode(); 

       //Get hash code for the ItemId field. 
       int hashCodeItemId = roadTaxDto.ItemId.GetHashCode(); 

       //Calculate the hash code for the QuoteTaxDto. 
       return hashVehicleId^hashCodeItemId; 
      } 

     } 

La structure RoadTaxDto ressemble à ceci:

class RoadTaxDto 
{ 
public int LineId {get;set} 
public string ItemDesc {get;set;} 
public int VehicleId {get;set;} 
public decimal RoadTax {get;set;} 
public int VehicleId {get;set;} 
public decimal Amount {get;set;} 
} 

J'utilise la commande suivante pour éliminer les doublons. Lorsque j'utilise un comparateur, je ne suis pas certain que la ligne 2 soit éliminée. Alors, comment puis-je m'assurer que si un enregistrement a un doublon, l'enregistrement qui dit "Aucun" sera toujours éliminé de la liste.

Répondre

0

Une approche "SQL" pure ne fonctionnerait pas pour vous?

Quelque chose comme ceci:

var list = new [] { 
    new RoadTaxDto {LineId=122317,ItemDesc="None", ItemId=-1,RoadTax =26.63M , VehicleId=-78603 ,Amount=300}, 
    new RoadTaxDto {LineId=122317,ItemDesc="None", ItemId=-2,RoadTax =17.75M , VehicleId=-78603 ,Amount=200}, 
    new RoadTaxDto {LineId=122317,ItemDesc="None", ItemId=-1,RoadTax =22.19M , VehicleId=-78602 ,Amount=250}, 
    new RoadTaxDto {LineId=122317,ItemDesc="Deli", ItemId=-2,RoadTax =17.75M , VehicleId=-78603 ,Amount=200} 
}; 

var query = (from c in list join x in list 
    on new { c.LineId, c.ItemId , c.VehicleId, c.Amount,c.RoadTax} 
equals new {x.LineId, x.ItemId, x.VehicleId,x.Amount,x.RoadTax} 
select new RoadTaxDto { 
    LineId = c.LineId, 
    ItemDesc = x.ItemDesc!="None"? x.ItemDesc:c.ItemDesc, 
    VehicleId=c.VehicleId, 
    Amount=c.Amount, 
    RoadTax=c.RoadTax, 
    ItemId=c.ItemId 
} 
).GroupBy(x => new { x.LineId, x.RoadTax, x.Amount, x.VehicleId}) 
.Select(grp => grp.Last()); 

Prints:

LineId ItemDesc VehicleId ItemId RoadTax Amount 
122317 None  -78603  -1  26.63 300 
122317 Deli  -78603  -2  17.75 200 
122317 None  -78602  -1  22.19 250 
+0

Avec cette approche, je voudrais doit se débarrasser de la RoadTaxComparer, mais cela fonctionne. Je vous remercie! – abhi

1

Je propose GetHashCode() à la RoadTaxDto puis faire:

foreach (var g in list.GroupBy(i => i.GetHashCode())) 
    list2.Add(
     g.FirstOrDefault(i => i.ItemDesc != "None") ?? 
     g.First()); 
+0

C'est une approche intéressante. Je vais l'essayer et vous le faire savoir. – abhi

Questions connexes