2013-08-02 79 views
3

我有一個列表,有一些重複。如何選擇一個記錄而不是另一個?

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 

在這種情況下,第2行是第4行的副本,因爲LineId,RoadTax,金額和VehicleId匹配。 不過,我想保持與項目描述行和消除線#2,所以我的輸出列表如下:

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 

我寫了一個基於MSDN上的例子的IEqualityComparer類。這個類看起來是這樣的:

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

     } 

的RoadTaxDto結構如下:

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

我用下面的命令來消除重複。

List<RoadTaxDto> mergedList = RoadTaxes.Union(RoadTaxes, new RoadTaxComparer()).ToList(); 

當我在它上運行比較器時,我不能保證第2行被消除。那麼我怎樣才能確保如果一條記錄有重複記錄,那麼說「無」的記錄總是會從列表中消除。

回答

0

純粹的「SQLish」方法不適合你?

事情是這樣的:

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

打印:

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

通過這種方法,我會必須擺脫RoadTaxComparer,但這是有效的。謝謝! – abhi

1

我會提出的GetHashCode()的RoadTaxDto,然後做到這一點:

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

這是一個有趣的方法。我會嘗試一下,讓你知道。 – abhi

相關問題