2011-01-12 3 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. Но также, Хенк Холтерман указал, что я переписывал свой результирующий набор на каждую итерацию, что было логической ошибкой.

  • Код Хенка, кажется, работает лучше всего, но мне нужно сделать больше испытаний.

  • Ответ Спинона также помог мне набраться ясности, но его код дал мне ошибку.

  • Мне нужно лучше понять код Тимви, но в его текущей форме это не сработало для меня.

НОВЫЙ КОД

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); 

Этот путь, а не переназначение переменной таблицы вы можете просто обновить его с новыми строк должны быть вставлены.

EDIT: Вот пример того, что я говорил:

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

О, начните с пустой таблицы, затем добавьте строки, соответствующие фильтру, отличная идея! * (Я думаю, Хенк предположил, что я уже думал об этих строках, oops, +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

Ошибка: 'Источник не содержит DataRows.' – JohnB

+0

Вы правы, это * wonky *, но, к сожалению, электронные таблицы ввода не были разработаны кем-то, кто твердо разбирается в концепциях реляционных таблиц. Вы знаете, как это происходит ... – JohnB

Смежные вопросы