2013-08-02 2 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는 LineId, RoadTax, 금액 및 VehicleId 일치하기 때문에, 행 4의 중복입니다.
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 클래스를 썼다 : 는 그러나, 나는 2. 그래서 내 출력 목록은 다음과 같습니다 라인 번호를 항목 설명과 라인을 유지하고 제거합니다.

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

순수한 "SQL"접근 방식이 효과가 없을까요? 이 같은

뭔가 :

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

나는이 할 다음 RoadTaxDto에 GetHashCode()를 이동 한 것이다 : 나는 것,이 방법

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

이것은 흥미로운 접근 방법입니다. 나는 그것을 밖으로 시도하고 알려드립니다. – abhi