Füllen eines DataSet oder einer DataTable aus einer LINQ-Abfrage-Ergebnismenge


137

Wie macht man eine LINQ-Abfrage als ASMX-Webdienst verfügbar? Normalerweise kann ich auf der Business-Ebene eine Eingabe zurückgeben DataSetoder DataTablediese für den Transport über ASMX serialisieren.

Wie kann ich dasselbe für eine LINQ-Abfrage tun? Gibt es eine Möglichkeit, eine Eingabe zu füllenDataSet oder DataTableeine LINQ-Abfrage zu füllen?

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;
}

Wie kann ich die Ergebnismenge einer LINQ-Abfrage in ein DataSetoder bekommen?DataTable ? Ist die LINQ-Abfrage alternativ serialisierbar, damit ich sie als ASMX-Webdienst verfügbar machen kann?

Antworten:


87

Wie in der Frage erwähnt, IEnumerablehat eine CopyToDataTableMethode:

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

Warum funktioniert das bei Ihnen nicht?


29
An alle, die sich fragen, warum CopyToDataTable () auf ihrem Computer nicht funktioniert: Diese Funktion ist weder Teil von .NET 3.5 SP1 noch von .NET 4.0. Es wurde auf IEnumerable <DataRows> beschränkt und funktioniert nicht für IEnumerable <T> - bit.ly/dL0G5
Motto

26

Um diese Abfrage für eine DataContextKlasse durchzuführen , müssen Sie Folgendes tun:

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

Ohne das as IEnumerable<DataRow>;wird der folgende Kompilierungsfehler angezeigt:

Der Typ 'System.Collections.Generic.IEnumerable' kann nicht implizit in 'System.Collections.Generic.IEnumerable' konvertiert werden. Es gibt eine explizite Konvertierung (fehlt Ihnen eine Besetzung?)


22

Erstellen Sie eine Reihe von Datenübertragungsobjekten, einige Mapper, und geben Sie diese über die .asmx-Datei zurück.
Sie sollten die Datenbankobjekte niemals direkt verfügbar machen, da eine Änderung des Prozedurschemas an den Webdienstkonsumenten weitergegeben wird, ohne dass Sie dies bemerken.


15

Wenn Sie einen Rückgabetyp von verwenden IEnumerable, können Sie Ihre Abfragevariable direkt zurückgeben.



2

Wenn Sie IEnumerableals Rückgabetyp verwenden, wird Ihre Abfragevariable direkt zurückgegeben.

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

Der Vollständigkeit halber funktionieren diese Lösungen nicht für EF Core (zumindest nicht für EF Core 2.2). Das Casting auf IEnumerable<DataRow>schlägt fehl, wie in den anderen Antworten hier vorgeschlagen. Die Implementierung dieser Klassen- und Erweiterungsmethoden funktionierte für mich unter https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/implement-copytodatatable-where-type-not-a-datarow .

Warum es nicht in EF Core eingebaut ist, weiß ich nicht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.