2011-01-12 2 views
1

저는 LINQ를 처음 사용 했으므로 아래 논리에 오류가 있다는 것을 확신합니다.행을 반환하지 않는 LINQ 쿼리

나는 개체의 목록을 가지고, 내가 개체 값에 따라 A A DataTable 시작 LINQ 쿼리 및 필터를 구축하려는 목록의 각 객체를 사용

class Characteristic 
{ 
    public string Name { get; set; } 
    public string Value { get; set; } 
    public bool IsIncluded { get; set; } 
} 

을하고, 그 결과로 DataTable가 산출됩니다. 지금까지

내 코드 :

DataTable table = MyTable; 
// Also tried: DataTable table = MyTable.Clone(); 

foreach (Characteristic c in characteristics) 
{ 
    if (c.IsIncluded) 
    { 
    var q = (from r in table.AsEnumerable() 
      where r.Field<string>(c.Name) == c.Value 
      select r); 

    table = rows.CopyToDataTable(); 
    } 
    else 
    { 
    var q = (from r in table.AsEnumerable() 
      where r.Field<string>(c.Name) != c.Value 
      select r); 

    table = q.CopyToDataTable(); 
    } 
} 

UPDATE

나는 당황한 서둘러 있었고, 난 실수를; 내 DataTable은 비어 있지 않았습니다. 단지 DataGrid에 바인딩하는 것을 잊었습니다. 또한, Henk Holterman은 논리 오류 인 각 결과를 덮어 쓰고 있다고 지적했습니다.

  • 헨크 코드가 지금까지 가장 잘 작동하는 것 같지만 테스트를 더해야합니다.

  • Spinon의 답변도 내 마음을 명확하게하는 데 도움이되었지만 코드가 오류를 발생 시켰습니다.

  • 나는 Timwi의 코드를 더 잘 이해하려고 노력할 필요가 있지만 현재의 형태로는 나에게 적합하지 않다. 그것은 단지 마지막 라운드의 결과를 보유하고 있으며 분명히 빈입니다 그 그래서 결국

NEW CODE는

DataTable table = new DataTable(); 

foreach (Characteristic c in characteristics) 
{ 
    EnumerableRowCollection<DataRow> rows = null; 

    if (c.IsIncluded) 
    { 
    rows = (from r in MyTable.AsEnumerable() 
      where r.Field<string>(c.Name) == c.Value 
      select r); 
    } 
    else 
    { 
    rows = (from r in MyTable.AsEnumerable() 
      where r.Field<string>(c.Name) != c.Value 
      select r); 
    } 

    table.Merge(rows.CopyToDataTable()); 
} 

dataGrid.DataContext = table; 

답변

1

당신은 각각의 특성에 대한 table 변수를 덮어 씁니다.

은 당신이 할 수있는 것은 같은 것입니다 :

// untested 
var t = q.CopyToDataTable(); 
table.Merge(t); 

그리고 난 당신의 쿼리가 소스로 MyTable에 사용해야합니다 의심 :

var q = (from r in MyTable.AsEnumerable() ... 

을하지만 그것은 완전히 분명하지 않다.

+1

필터를 모두 적용하려면 * 덮어 쓰고 싶습니다. 첫 번째 반복 후에도 테이블이 비어있는 것처럼 보입니다. 이것이 바로이 코드 블록에 대한 새로운 'DataTable'참조를 만드는 이유이기도합니다. – JohnB

1

그냥 다음 테이블에 행을 삽입 CopyToDataTable 방법이 방법으로 호출하려고 시도하는 경우 :

q.CopyToDataTable(table, LoadOption.PreserveChanges); 

이 방법보다는 그냥 새 행으로 업데이트 할 수 있습니다 테이블 변수를 재 할당하는 삽입해야합니다.

편집 : 저는 여기에 대해 말하고 있었는지의 예는 다음과 같습니다

DataTable table = new DataTable(); 
table.Columns.Add("Name", typeof(string)); 
table.Columns.Add("Value", typeof(string)); 
+1

아, 빈 테이블로 시작한 다음 필터와 일치하는 행을 추가하십시오. * (나는 헨크가 이미 그 선들에 대해 생각하고 있다고 생각했다.) * – JohnB

+2

@Henk이 말한 것은 그것이 매치 할 때마다 테이블 변수를 덮어 쓰는 것으로 보인다고 생각한다. 그래서 모든 필터에 대해 모든 일치 대신 표에서 일치하는 행의 마지막 세트 만 사용하게됩니다. – spinon

+0

오류 :'입력 배열이이 테이블의 열 개수보다 깁니다. ' – JohnB

3

귀하의 게시물의 논리가 남았습니다입니다; 여기에 내 시도가 무엇입니까 당신이 달성하려고합니다.

DataTable table = MyTable.AsEnumerable() 
    .Where(r => characteristics.All(c => !c.IsIncluded || 
              r.Field<string>(c.Name) == c.Value)) 
    .CopyToDataTable(); 

실제로 ^||을 변경, 당신의 게시물에 논리를 사용하려면

,하지만 약간의 이해가 보인다.

+0

Error :'소스에 DataRow가 없습니다 .' – JohnB

+0

당신이 맞습니다. * wonky *이지만, 유감스럽게도 입력 스프레드 시트는 관계형 테이블 개념을 확실히 이해하고있는 사람이 디자인 한 것이 아닙니다. 그게 어떻게되는지 알아. – JohnB