Заповнення набору даних або таблиці даних із набору результатів запиту LINQ


137

Як ви піддаєте 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?

Відповіді:


87

Як було сказано у запитанні, 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>();

Чому це не допоможе тобі?


29
Для всіх, хто цікавиться, чому CopyToDataTable () не працює на своїй машині: Ця функція не є частиною .NET 3.5 SP1, і не буде .NET 4.0; він обмежений IEnumerable <DataRows> і не працює для IEnumerable <T> - bit.ly/dL0G5
девіз

26

Щоб виконати цей запит проти 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". Існує явна конверсія (пропускаєш амплуа?)


22

Створіть набір Об'єктів передачі даних, пару картографів, і поверніть це через .asmx. Ніколи не
слід піддавати об’єктам бази даних безпосередньо, оскільки зміна схеми процедур поширюється на споживача веб-сервісу, не помічаючи цього.


15

Якщо ви використовуєте тип повернення IEnumerable, ви можете повернути змінну запиту безпосередньо.



2

Якщо ви використовуєте 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>();

0

Для повноти ці рішення не працюють для 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, я не маю уявлення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.