2013-08-02 3 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 является дубликатом Row 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 

Я написал IEqualityComparer класс на основе, например, на сайте MSDN. Класс выглядит следующим образом:

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

Я использую следующую команду для устранения дубликатов.

Когда я запускаю на нем компаратор, я не гарантирую, что строка 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