Копировать результаты LINQ в набор данных / таблицу - PullRequest
1 голос
/ 24 июня 2011

Я работаю над формой, в которой есть несколько представлений сетки данных, которые заполнены запросами LINQ, там нет проблем, это работает так, как должно, однако сортировка не работает. После некоторого чтения, потому что результаты LINQ не поддерживают сортировку.

Поскольку у меня уже есть результаты LINQ, есть ли способ скопировать результаты в набор данных или таблицу данных, а затем связать представление сетки данных с этим, чтобы сортировка работала?

Спасибо

EDIT: Спасибо всем за ответы, к сожалению, я ухожу в отпуск на 2 недели, поэтому не могу попробовать и поставить правильный ответ. Однако, когда я вернусь, он будет на вершине моего списка

Ответы [ 4 ]

2 голосов
/ 12 июля 2011

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

Первое, что нужно сделать, - это скопировать функцию CopyToDataTable в VB, это делается здесь

http://msdn.microsoft.com/en-us/library/bb669096.aspx

Когда я попробовал это, произойдет сбой, если столбец обнулится, поэтому я искал и нашел мод для этого кода, который будет работать.Вот оно в полном объеме

Public Function ExtendTable(ByVal table As DataTable, ByVal type As Type) As DataTable
     For Each f As FieldInfo In type.GetFields()
       If (Not _ordinalMap.ContainsKey(f.Name)) Then
         Dim dc As DataColumn
         dc = If(table.Columns.Contains(f.Name), table.Columns(f.Name), table.Columns.Add(f.Name, f.FieldType))
         _ordinalMap.Add(f.Name, dc.Ordinal)
       End If
     Next f
     For Each p As PropertyInfo In type.GetProperties()
       If Not _ordinalMap.ContainsKey(p.Name) Then
         Dim colType As Type = p.PropertyType
         If (colType.IsGenericType) AndAlso (colType.GetGenericTypeDefinition() Is GetType(Nullable(Of ))) Then
           colType = colType.GetGenericArguments()(0)
         End If
         Dim dc As DataColumn = IIf(table.Columns.Contains(p.Name), table.Columns(p.Name), table.Columns.Add(p.Name, colType))
         _ordinalMap.Add(p.Name, dc.Ordinal)
       End If
     Next
     Return table
    End Function

Повышение голосов по всему кругу, так как все они работали бы. Я просто выбрал этот вариант, так как он более аккуратный

2 голосов
/ 24 июня 2011

Для этого можно использовать метод расширения CopyToDataTable.

Стандартная реализация этого метода работает только для IEnumerable<T>, где T имеет тип DataRow, но естьпример на MSDN создания собственного метода расширения , который работает с анонимными типами .


Я на самом деле не использовал CopyToDataTable, в прошлом я создавал аналогичныйконечный результат - создание BindingList, который поддерживает сортировку, а затем создание его экземпляра с запросом в качестве IList в конструкторе, но подход CopyToDataTable выглядит для меня чище.

1 голос
/ 24 июня 2011

См. Код:

Здесь testData - это данные запроса LINQ к списку классов, имеющих ID и имя в качестве свойств

  Dim dataTable As New DataTable()
        dataTable.Columns.Add("ID", GetType(Integer))
        dataTable.Columns.Add("Name", GetType(String))
        For Each item As var In testData
        Dim dataRow As DataRow = dataTable.NewRow()
        dataRow("ID") = item.ID
        dataRow("Name") = item.Name
        dataTable.Rows.Add(dataRow)
        Next
1 голос
/ 24 июня 2011

В C # я делаю это так:

        DataTable dt = new DataTable();
        dt.Columns.Add("a", Type.GetType("System.String"));
        dt.Columns.Add("b", Type.GetType("System.String"));
        dt.Columns.Add("c", Type.GetType("System.String"));
        dt.Columns.Add("d", Type.GetType("System.String"));

        foreach (var row in [linqQueryName] )
        {
            DataRow destRow = dt.NewRow();
            destRow["a"] = row.linqCol1;
            destRow["b"] = row.linqCol2;
            destRow["c"] = row.linqCol3;
            destRow["d"] = row.linqCol4;
            dt.Rows.Add(destRow);
        }
...