2009-11-06 1 views
1

csharp의 DataSet에서 고유 값을 검색하는 데 문제가 있습니다. 가능합니까? C# DataSet - 열을 기반으로 고유 값 가져 오기

사실 나는 웹 서비스에서 데이터 집합을 얻을이 같은 일을 해요 :
webService.getInstructions(Username, Password, AppKey).Tables[0].Select(null, "account name asc"); 

그래서이 경우에는 내가 계정에서 알파벳 목록을, 그러나이 데이터 집합에서 일부 중복 행이 있습니다.

독특한 "계좌 번호"이 데이터 집합의 반환 값을 확인하고 "계정 이름" 알파벳 순으로 정렬 할 수있는 방법이 있나요?

무언가가 필터 표현 일 것이라고 생각합니다. :) 내가 웹 서비스를 변경 거라고 개인적으로

답변

3

사전에

덕분에이 필터링을 수행하고 서버에 정렬하는 것은 (아마 간단한 데이터 유형 또는 사용자 정의 클래스를 반환 대역폭 요구를하지 줄이기 위해 DataTable 또는 이와 유사한 것). 그러나 LINQ는 사용자에게 DistinctBy 방법을 사용 (다시 읽기 질문 후에 업데이트) 작업 ...

var rows = dataset.Tables[0].AsEnumerable() 
    .DistinctBy(row => row.Field<string>("account number")) 
    .OrderBy(row => row.Field<string>("account name")) 
    .ToArray(); 

할 것 :

static IEnumerable<TSource> DistinctBy<TSource, TValue>(
     this IEnumerable<TSource> source, 
     Func<TSource, TValue> selector) 
    { 
     HashSet<TValue> unique = new HashSet<TValue>(); 
     foreach (var item in source) 
     { 
      if (unique.Add(selector(item))) yield return item; 
     } 
    } 
+0

감사합니다. Marc는 매우 훌륭하게 작동했습니다. 그렇습니다. 웹 서비스에서 직접 설정할 수 있다는 점에서 완전히 동의하지만 불행히도 저는 액세스 할 수 없습니다. 그러나 당신의 도움에 감사드립니다! :) – zanona

0

본인은 데이터 테이블에 약간의 LINQ 마법을 사용합니다.

 DataTable dt = new DataTable(); 
     dt.Columns.Add(new DataColumn("AccountNumber", typeof(System.Int32))); 
     dt.Columns.Add(new DataColumn("AccountName", typeof(System.String))); 

     for (int ii = 0; ii < 20; ii++) 
      dt.Rows.Add(new object[]{ii, "abc" + ii.ToString()}); 

     dt.Rows[6][0] = 5; 
     dt.Rows[7][0] = 5; 
     dt.Rows[8][0] = 5; 

     //using grouping to isolate groups with just one item 
     var groupedRows = from row in dt.Select("", "AccountName ASC") 
          group row by row["AccountNumber"] into rowGroup 
          where rowGroup.Count() == 1 
          select rowGroup; 

     foreach (var group in groupedRows) 
      foreach(DataRow dr in group) 
       Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]); 


     //using nested select to avoid grouping 
     Console.WriteLine(); 
     Console.WriteLine("Nested select"); 
     var z = from row in dt.Select() 
       where (from x in dt.Select() where (int) x["AccountNumber"] == (int) row["AccountNumber"] select x).Count() == 1 
       orderby row["AccountName"] 
       select row; 

     foreach(DataRow dr in z) 
      Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]); 


     Console.WriteLine(); 
     Console.WriteLine("Datatable select"); 
     var y = from row in dt.Select() 
       where (from x in dt.Select("AccountNumber = " + row["AccountNumber"]) select x).Count() == 1 
       orderby row["AccountName"] 
       select row; 

     foreach (DataRow dr in y) 
      Console.WriteLine("Account #: {0} Account name: {1}", dr["AccountNumber"], dr["AccountName"]); 

결과가 화면에 인쇄되면 AccountNumber가 '5'인 행이 고유하지 않으므로 누락되었습니다. 또한 첫 번째 예제에서는 dataTable.Select()를 사용하여 순서를 지정했습니다. 고유하지 않기 때문에 행이 제거되는 것과 관계없이 순서가 동일하므로주의해야합니다. 두 번째와 세 번째 샘플은 직접 바인드 할 수있는 IEnumerable 행 목록을 제공하며, 첫 번째 행은 개별 행을 포함하는 그룹을 제공합니다.