2012-05-24 2 views
6

목록이 있습니다. 목록의 모든 데이터 테이블에있는 모든 행을 찾으려면 테이블 목록의 모든 행을 필터링하고 싶습니다.DataTable 목록에서 교차하는 DataRow 찾기

가능한 경우 비교는 모든 행에있는 "ID"열에 있어야합니다.

나는 이것을 Linq로 풀려고했지만 막혔다. 이것은 내가 지금까지 가지고있는 것입니다 :

List<DataTable> dataTables = new List<DataTable>(); 

// fill up the list 
List<DataRow> dataRows = 
    dataTables.SelectMany(dt => dt.Rows.Cast<DataRow>().AsEnumerable()). 
    Aggregate((r1, r2) => r1.Intersect(r2)); 

어떤 제안이 있습니까?

+0

과거에 Intersect를 사용해 왔을 때마다 언제든지 평등 비교가 이루어졌습니다. 기본 유형의 Enumerables를 사용하여 작업하는 것이 일반적으로 좋지만 복잡한 유형은 항상 비교할 때 무시해야했습니다. . 아직 조사하지 않았다면 조사 할만한 가치가 있습니다. – SpaceBison

답변

4

하지 간단한 질문을. 여기에 해결책이 있습니다 (너무 복잡해 보이지만 작동합니다).

  • 의 하나가 모든 행에있는 모든 일반
  • 값 행의 하나의 선두로부터 찾기를 찾기 위해 데이터 집합에 여러 목록 교차
  • 을 Linq를 사용하여 각 행의 ID 값을 가져옵니다 일치하는 ID

DataTable에서 Linq를 사용하려면 시작하려면 this article을 참조하십시오.

당신은 this article을 시도, 여러 목록을 교차하기 위해 여러 테이블

var setsOfIds = dataTables.Select (
    t => t.AsEnumerable().Select (x => x.Field<int>("ID")).OfType<int>()); 

var ids = dt.AsEnumerable().Select (d => d.Field<int>("ID")).OfType<int>(); 

같은과에서 하나 개의 테이블에서 ID를 얻을 수 있습니다. 거기에있는 메소드 중 하나를 사용하여 모든 ID의 교차 부분을 얻을 수 있습니다.

var rows = dataTables.SelectMany (t => t.AsEnumerable()).Where(
    r => commonIds.Contains(r.Field<int>("ID"))); 

해주기 그룹 : 우리가

이제
var commonIds = setsOfIds.InsersectAll(); 

공통 식별자에 의해 DataTables 및 필터의 모든 행을 평평하게 쓸 수있는 존 소총의 도우미 방법

public static class MyExtensions 
{ 
    public static List<T> IntersectAll<T>(this IEnumerable<IEnumerable<T>> lists) 
    { 
     HashSet<T> hashSet = new HashSet<T>(lists.First()); 
     foreach (var list in lists.Skip(1)) 
     { 
      hashSet.IntersectWith(list); 
     } 
     return hashSet.ToList(); 
    } 
} 

를 사용

id로 각 행의 첫 번째 인스턴스를 가져옵니다.

var result = rows.GroupBy (r => r.Field<int>("ID")).Select (r => r.First()); 
1

두 목록 사이의 교차점을 찾기 위해이 시도 :

r1.Join(r2, r1 => r1.Id, r2 => r2.Id, (r1, r2) => r1);