Лучшая практика: преобразование результата запроса LINQ в DataTable без цикла
Какова наилучшая практика преобразования результата LINQ-Query в новый DataTable
?
могу ли я найти решение лучше, чем foreach
каждого результата результата?
ИЗМЕНИТЬ
AnonymousType
var rslt = from eisd in empsQuery
join eng in getAllEmployees()
on eisd.EMPLOYID.Trim() equals eng.EMPLOYID.Trim()
select new
{
eisd.CompanyID,
eisd.DIRECTID,
eisd.EMPLOYID,
eisd.INACTIVE,
eisd.LEVEL,
eng.EnglishName
};
ИЗМЕНИТЬ 2:
У меня есть исключение:
Локальная последовательность не может использоваться в реализации операторов запросов LINQ to SQL, кроме оператора Contains().
когда я пытаюсь выполнить запрос
и нашел решение здесь IEnumerable.Except wont work, так что мне делать? и Нужна помощь по linq
Ответы
Ответ 1
Используйте Linq для набора данных. Из MSDN: Создание DataTable из запроса (LINQ to DataSet)
// Query the SalesOrderHeader table for orders placed
// after August 8, 2001.
IEnumerable<DataRow> query =
from order in orders.AsEnumerable()
where order.Field<DateTime>("OrderDate") > new DateTime(2001, 8, 1)
select order;
// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();
Если у вас есть анонимные типы:
Из блога Coder: Использование анонимных типов Linq и CopyDataTable
В нем объясняется, как использовать MSDN Практическое руководство. Реализация CopyToDataTable, где общий тип T не является DataRow
Ответ 2
Преобразование результата запроса в универсальную функцию DataTables
DataTable ddt = new DataTable();
ddt = LINQResultToDataTable(query);
public DataTable LINQResultToDataTable<T>(IEnumerable<T> Linqlist)
{
DataTable dt = new DataTable();
PropertyInfo[] columns = null;
if (Linqlist == null) return dt;
foreach (T Record in Linqlist)
{
if (columns == null)
{
columns = ((Type)Record.GetType()).GetProperties();
foreach (PropertyInfo GetProperty in columns)
{
Type colType = GetProperty.PropertyType;
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
== typeof(Nullable<>)))
{
colType = colType.GetGenericArguments()[0];
}
dt.Columns.Add(new DataColumn(GetProperty.Name, colType));
}
}
DataRow dr = dt.NewRow();
foreach (PropertyInfo pinfo in columns)
{
dr[pinfo.Name] = pinfo.GetValue(Record, null) == null ? DBNull.Value : pinfo.GetValue
(Record, null);
}
dt.Rows.Add(dr);
}
return dt;
}
Ответ 3
Используйте System.Reflection и итерацию для каждой записи в объекте запроса.
Dim dtResult As New DataTable
Dim t As Type = objRow.GetType
Dim pi As PropertyInfo() = t.GetProperties()
For Each p As PropertyInfo In pi
dtResult.Columns.Add(p.Name)
Next
Dim newRow = dtResult.NewRow()
For Each p As PropertyInfo In pi
newRow(p.Name) = p.GetValue(objRow,Nothing)
Next
dtResult.Rows.Add(newRow.ItemArray)
Return dtResult
Ответ 4
Я использую пакет morelinq.2.2.0 в веб-приложении asp.net, консоль менеджера пакетов Nuget
PM> Install-Package morelinq
Пространство имен
using MoreLinq;
Моя выборочная хранимая процедура sp_Profile(), которая возвращает данные профиля
DataTable dt = context.sp_Profile().ToDataTable();