Wypełnianie DataSet lub DataTable z zestawu wyników zapytania LINQ

137

Jak udostępnić zapytanie LINQ jako usługę sieciową ASMX? Zwykle z poziomu biznesowego mogę zwrócić wpisany DataSetlub DataTableserializowany do transportu przez ASMX.

Jak mogę zrobić to samo dla zapytania LINQ? Czy istnieje sposób na wypełnienie wpisanego DataSetlub DataTableza pośrednictwem zapytania 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;
}

Jak mogę uzyskać zestaw wyników zapytania LINQ do DataSetlub DataTable? Alternatywnie, czy zapytanie LINQ można serializować, aby można było je ujawnić jako usługę sieci Web ASMX?

Geoff Dalgas
źródło

Odpowiedzi:

87

Jak wspomniano w pytaniu, IEnumerablema CopyToDataTablemetodę:

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>();

Dlaczego to nie zadziała?

Jon Galloway
źródło
29
Do wszystkich, którzy zastanawiają się, dlaczego CopyToDataTable () nie działa na ich komputerze: Ta funkcja nie jest częścią .NET 3.5 SP1 ani nie będzie w .NET 4.0; został ograniczony do IEnumerable <DataRows> i nie działa dla IEnumerable <T> - bit.ly/dL0G5
motto
26

Aby wykonać to zapytanie w stosunku do DataContextklasy, musisz wykonać następujące czynności:

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>();

Bez tego as IEnumerable<DataRow>;zobaczysz następujący błąd kompilacji:

Nie można niejawnie przekonwertować typu „System.Collections.Generic.IEnumerable” na „System.Collections.Generic.IEnumerable”. Istnieje jawna konwersja (brakuje Ci obsady?)

C1pher
źródło
22

Stwórz zestaw obiektów transferu danych, kilka mapperów i zwróć go za pośrednictwem pliku .asmx.
Nigdy nie należy bezpośrednio ujawniać obiektów bazy danych, ponieważ zmiana w schemacie procedury będzie propagowana do konsumenta usługi WWW bez zauważenia tego.

Lars Mæhlum
źródło
15

Jeśli używasz zwracanego typu IEnumerable, możesz bezpośrednio zwrócić zmienną zapytania .

Dave Ward
źródło
11

Utwórz obiekt klasy i zwróć list(T)zapytanie.

Brian Childress
źródło
2

Jeśli użyjesz IEnumerablejako typu zwracanego, zwróci on bezpośrednio zmienną zapytania.

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>();
Vijay S
źródło