Mengisi Kumpulan Data atau Tabel Data dari kumpulan hasil kueri LINQ

137

Bagaimana Anda mengekspos kueri LINQ sebagai layanan web ASMX? Biasanya, dari tingkat bisnis, saya dapat mengembalikan yang diketik DataSetatau DataTableyang dapat diserialkan untuk diangkut melalui ASMX.

Bagaimana saya bisa melakukan hal yang sama untuk kueri LINQ? Apakah ada cara untuk mengisi kueri yang diketik DataSetatau DataTablemelalui 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;
}

Bagaimana saya bisa mendapatkan hasil dari query LINQ menjadi DataSetatau DataTable? Atau, apakah kueri LINQ dapat diserialkan sehingga saya dapat memaparkannya sebagai layanan web ASMX?

Geoff Dalgas
sumber

Jawaban:

87

Seperti yang disebutkan dalam pertanyaan, IEnumerablememiliki CopyToDataTablemetode:

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

Mengapa itu tidak berhasil untuk Anda?

Jon Galloway
sumber
29
Untuk semua orang yang bertanya-tanya mengapa CopyToDataTable () tidak berfungsi di mesin mereka: Fungsi ini bukan bagian dari .NET 3.5 SP1 juga bukan dari .NET 4.0; itu telah dibatasi untuk IEnumerable <DataRows> dan tidak berfungsi untuk IEnumerable <T> - bit.ly/dL0G5
motto
26

Untuk melakukan kueri ini terhadap sebuah DataContextkelas, Anda perlu melakukan hal berikut:

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

Tanpa as IEnumerable<DataRow>;Anda akan melihat kesalahan kompilasi berikut:

Tidak dapat secara implisit mengonversi jenis 'System.Collections.Generic.IEnumerable' menjadi 'System.Collections.Generic.IEnumerable'. Ada konversi eksplisit (apakah Anda kehilangan pemeran?)

C1pher
sumber
22

Buat satu set Objek Transfer Data, beberapa pembuat peta, dan kembalikan melalui .asmx.
Anda tidak boleh mengekspos objek database secara langsung, karena perubahan dalam skema prosedur akan menyebar ke konsumen layanan web tanpa Anda sadari.

Lars Mæhlum
sumber
15

Jika Anda menggunakan tipe kembalian IEnumerable, Anda bisa mengembalikan variabel kueri Anda secara langsung.

Dave Ward
sumber
11

Buat objek kelas dan kembalikan list(T)kueri.

Brian Childress
sumber
2

Jika Anda menggunakan IEnumerablesebagai tipe pengembalian, itu akan mengembalikan variabel kueri Anda secara langsung.

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
sumber