Как представить запрос 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?





Если вы используете тип возврата IEnumerable, вы можете напрямую вернуть свою переменную запрос.
Создайте объект класса и верните list(T) запроса.
Как упоминалось в вопросе, 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>();
Почему это не сработает для вас?
Создайте набор объектов передачи данных, пару мапперов и верните их через .asmx.
.
Вы должны никогда напрямую открывать объекты базы данных, поскольку изменение схемы процедуры будет распространяться на потребителя веб-службы, а вы этого не заметите.
Чтобы выполнить этот запрос к классу 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>; вы увидите следующую ошибку компиляции:
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?)
Если вы используете 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>();
Для полноты картины эти решения не работают для 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.
Всем, кто задается вопросом, почему CopyToDataTable () не работает на их компьютере: эта функция не является частью .NET 3.5 SP1 и не будет частью .NET 4.0; он был ограничен IEnumerableи не работает для IEnumerable- bit.ly/dL0G5