Llenar un DataSet o DataTable desde un conjunto de resultados de consulta LINQ

137

¿Cómo expones una consulta LINQ como un servicio web ASMX? Por lo general, desde el nivel empresarial, puedo devolver un tipo DataSeto DataTableque se puede serializar para el transporte a través de ASMX.

¿Cómo puedo hacer lo mismo para una consulta LINQ? ¿Hay alguna manera de completar una consulta escrita DataSeto DataTablemediante 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;
}

¿Cómo puedo obtener el conjunto de resultados de una consulta LINQ en un DataSeto DataTable? Alternativamente, ¿la consulta LINQ es serializable para que pueda exponerla como un servicio web ASMX?

Geoff Dalgas
fuente

Respuestas:

87

Como se menciona en la pregunta, IEnumerabletiene un CopyToDataTablemétodo:

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

¿Por qué eso no funcionará para ti?

Jon Galloway
fuente
29
Para todos los que se preguntan por qué CopyToDataTable () no funciona en su máquina: esta función no es parte de .NET 3.5 SP1 ni será de .NET 4.0; se ha restringido a IEnumerable <DataRows> y no funciona para IEnumerable <T> - bit.ly/dL0G5
lema
26

Para realizar esta consulta en una DataContextclase, deberá hacer lo siguiente:

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

Sin el as IEnumerable<DataRow>;, verá el siguiente error de compilación:

No se puede convertir implícitamente el tipo 'System.Collections.Generic.IEnumerable' a 'System.Collections.Generic.IEnumerable'. Existe una conversión explícita (¿te falta un yeso?)

C1pher
fuente
22

Haga un conjunto de objetos de transferencia de datos, un par de mapeadores y devuélvalos a través de .asmx.
Usted debe nunca se exponen los objetos de base de datos directamente, como un cambio en el esquema de procedimiento se propagará al consumidor de servicios web sin que se dé cuenta.

Lars Mæhlum
fuente
15

Si utiliza un tipo de retorno de IEnumerable, puede devolver su variable de consulta directamente.

Dave Ward
fuente
11

Cree un objeto de clase y devuelva una list(T)de la consulta.

Brian Childress
fuente
2

Si lo utiliza IEnumerablecomo tipo de retorno, devolverá su variable de consulta directamente.

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
fuente