2011-01-12 263 views
1

我是LINQ的新手,所以我確信在我的邏輯中有一個錯誤。LINQ查詢不返回行

我有對象的列表:

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

使用列表中的每個對象,我希望它基於對象值建立在LINQ查詢與一個DataTable開始,過濾器和作爲結果產生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的代碼,但在目前的形式下,它並不適合我。

新規範

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

我想覆蓋它,因爲我想應用* ALL *過濾器。即使在第一次迭代之後,表格也顯示爲空。這也是我選擇爲這個代碼塊創建一個新的`DataTable`引用的原因。 – JohnB 2011-01-12 18:56:09

1

如果你想剛插入行到表中,然後嘗試調用CopyToDataTable方法是這樣的:

q.CopyToDataTable(table, LoadOption.PreserveChanges); 

這種方式,而不是重新分配表變量你可以用新的行更新是被插入。

編輯:這是我在談論的一個例子:

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

哦,從一個空表開始,然後添加匹配過濾器的行,好主意! *(我認爲Henk認爲我已經在考慮這些問題了,oops,還有+1。)* – JohnB 2011-01-12 19:02:54

+2

我認爲@Henk說的是,每當你找到一個匹配的時候,你就會覆蓋你的表變量。這就是爲什麼充其量只有你的表中最後一組匹配的行,而不是每個過濾器的所有匹配。 – spinon 2011-01-12 19:05:36

3

在你的帖子的邏輯是靠不住的;這裏是我想要嘗試實現的認爲的嘗試。

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

如果你真的想使用邏輯在你的帖子,改變||^,但似乎沒有意義。