2011-01-10 3 views
0

데이터 테이블이 있는데 결과에서 모든 고유 한 이름을 선택하려고합니다. 나는 그것을 위해 linq 쿼리를 썼다.C# linq 질문

var distinctRows = (from DataRow myDataRow in myDataTable.Rows 
        select new { col1 = myDataRow ["Name"]}).Distinct(); 

어떻게 distinctRows를 반복합니까? 내가 할 수없는 것 같아요, 나에게 " 'System.Data.DataRow' '형식으로'익명 형식 # 1 '형식을 변환 할 수 없습니다"오류

+4

오류를 읽고 계하십니까? – SLaks

+4

질문 제목에 귀하의 질문이 기술되어 있다면 앞으로 더 나은 결과를 얻을 수있을 것입니다. "C# linq question"은 아무 것도 알려주지 않습니다. C#과 linq는 이미 태그이며 우리는 그 질문을 알고 있습니다. –

+0

@Eric, 지적 해 주셔서 고맙습니다. 바보 같은 제목을 사용하여 미안 해요 :) – imak

답변

3

하나의 필드 만 선택했기 때문에 여기에 익명 형식이 필요하지 않습니다. 이름을 선택한 다음 다른 이름으로 반복하십시오. 위트로 :

var distinctNames = (from DataRow myDataRow in myDataTable.Rows 
        select myDataRow.Field<string>("Name") 
        ).Distinct(); 

foreach(var name in distinctNames) { 
    Console.WriteLine(name); 
} 

오류로 인해 여기에 어떤 문제가 있는지 명확히 알 수 있습니다. 익명 형식의 인스턴스를 DataRow의 인스턴스로 변환하려고합니다. 불가능합니다. 당신의 코드를 변경하지 않고, 당신은

foreach(var item in distinctRows) { 
    Console.WriteLine((string)item.col1); 
} 

으로 이것을 반복 할 수 있지만 익명 형식을 필요로하지 않으며, 당신의 변수 이름과 필드 이름이 가난한 나는 위의에 따라 변경할 것입니다.

+0

그것은 '객체'입니다. – SLaks

2

이들은 DataRow가 아닙니다; 그들은 익명의 객체입니다.
루프를 반복하려면 var 키워드를 사용하여 변수를 선언해야합니다.

그러나 처음에는 익명 유형이 없습니다.
쿼리를 select myDataRow.Field<string>("Name")으로 변경하면 일련의 문자열을 가져올 수 있습니다.

+0

예를 들어 줄 수 – imak

+1

예를 들어 왜 필요합니까? 실제로 오류를 읽은 경우 솔루션이 분명해야합니다. – SLaks

0

myDataRow["Name"]DataRow을 반환하지 않기 때문입니다. 시도해보십시오.

foreach(var item in distinctRows) {} 
1

키워드 var을 사용하여 익명 유형 (IEnumerable<>을 반환 함)을 참조 할 수 있습니다.

foreach(var row in distinctRows) 
{ 
    // do something with each anonymous type instance 
} 

당신은 반환 값이 DataRow를하지 않기 때문에 당신은뿐만 아니라입니다 IEnumerable<string>

0

을 투사 할 수있다, 그러나 하나 개의 문자열 속성과 익명 형식을 반환하는 것입니다. 이것은 col1 속성을 포함하는 ad-hoc 유형입니다.

0

SLaks 응답을 기반으로합니다. . .

0

여기서 문제는 실제 행 자체가 아닌 select new { col1 = myDataRow ["Name"]}을 수행하여 새로운 익명 유형을 선택한다는 것입니다. 따라서 이것을 DataRow로 반복하려고하면 익명 형식이 DataRow 형식이 아니기 때문에 오류가 발생합니다.

이름 필드뿐만 아니라 전체 데이터 행을 선택할 수있게하려면 데이터 행이 Distinct() 확장 메소드에 전달되도록 맞춤 IEqualityComparer을 구현해야합니다.를 사용하여 다음

public class NameComparer : IEqualityComparer<DataRow> 
{ 
    public bool Equals(DataRow left, DataRow right) 
    { 
     return left.Field<string>("Name").Equals(right.Field<string>("Name")); 
    } 

    public int GetHashCode(DataRow obj) 
    { 
     return obj.ToString().GetHashCode(); 
    } 
} 

:

예로들 수

var distinctRows = (from DataRow myDataRow in myDataTable.Rows 
        select myDataRow).Distinct(new NameComparer()); 
0

또한 그들을 foreach는 할 수 있지만 먼저 다음과 같은를 나열했다 :

List<string> rslt =(from DataRow myDataRow in myDataTable.Rows 
        select new { col1 = myDataRow ["Name"].ToString()}).Distinct().ToList(); 

foreach(string str in rlst) 
{} 

희망이 도움을주었습니다