Заполнение DataSet или DataTable из набора результатов запроса LINQ
Как вы представляете запрос LINQ как веб-сервис ASMX? Обычно из бизнес-уровня я могу вернуть типизированный DataSet
или DataTable
который можно сериализовать для передачи через ASMX.
Как я могу сделать то же самое для запроса LINQ? Есть ли способ заполнить типизированный DataSet
или DataTable
через запрос LINQ?
public static MyDataTable CallMySproc()
{
string conn = "...";
MyDatabaseDataContext db = new MyDatabaseDataContext(conn);
MyDataTable dt = new MyDataTable();
// execute a sproc via LINQ
var query = from dr
in db.MySproc().AsEnumerable
select dr;
// copy LINQ query resultset into a DataTable -this does not work !
dt = query.CopyToDataTable();
return dt;
}
Как я могу получить набор результатов запроса LINQ в DataSet
или DataTable
? В качестве альтернативы, можно ли сериализовать запрос LINQ, чтобы я мог представить его в качестве веб-службы ASMX?
Ответы
Ответ 1
Как упоминалось в вопросе, IEnumerable
имеет метод CopyToDataTable
:
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>();
Почему это не будет работать для вас?
Ответ 2
Чтобы выполнить этот запрос с классом DataContext
, вам необходимо сделать следующее:
MyDataContext db = new MyDataContext();
IEnumerable<DataRow> query =
(from order in db.Orders.AsEnumerable()
select new
{
order.Property,
order.Property2
})
as IEnumerable<DataRow>;
return query.CopyToDataTable<DataRow>();
Без as IEnumerable<DataRow>;
вы увидите следующую ошибку компиляции:
Невозможно неявно преобразовать тип 'System.Collections.Generic.IEnumerable' в 'System.Collections.Generic.IEnumerable'. Явное преобразование существует (вы пропускаете листинг?)
Ответ 3
Сделайте набор объектов передачи данных, пару картографов и верните их через .asmx.
Вы никогда не должны напрямую открывать объекты базы данных, так как изменение схемы процедуры будет распространяться на пользователя веб-службы без вашего уведомления.
Ответ 4
Если вы используете тип возврата IEnumerable
, вы можете напрямую вернуть свою переменную запрос.
Ответ 5
Создайте объект класса и верните list(T)
запроса.
Ответ 6
Если вы используете возвращаемый тип IEnumerable
Он помогает возвращать вашу переменную запроса напрямую.
MyDataContext db = new MyDataContext();
IEnumerable<DataRow> query =
(from order in db.Orders.AsEnumerable()
select new
{
order.Property,
order.Property2
})
as IEnumerable<DataRow>;
return query.CopyToDataTable<DataRow>();
Ответ 7
Для полноты картины эти решения не работают для EF Core (по крайней мере, для EF Core 2.2). Приведение к IEnumerable<DataRow>
, как предлагается в других ответах, завершается неудачно. Реализация этого класса и методов расширения работала для меня https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/implement-copytodatatable-where-type-not-a-datarow.
Почему это не встроено в EF Core, я понятия не имею.