Preenchendo um DataSet ou DataTable a partir de um conjunto de resultados da consulta LINQ

137

Como você expõe uma consulta LINQ como um serviço da Web ASMX? Normalmente, na camada de negócios, posso retornar um tipo digitado DataSetou DataTableque pode ser serializado para transporte no ASMX.

Como posso fazer o mesmo para uma consulta LINQ? Existe uma maneira de preencher uma consulta digitada DataSetou DataTablevia 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;
}

Como posso obter o conjunto de resultados de uma consulta LINQ em um DataSetou DataTable? Como alternativa, a consulta LINQ é serializável para que eu possa expô-la como um serviço da Web ASMX?

Geoff Dalgas
fonte

Respostas:

87

Como mencionado na pergunta, IEnumerabletem um 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 que isso não funciona para você?

Jon Galloway
fonte
29
Para todos que se perguntam por que CopyToDataTable () não funciona em suas máquinas: Esta função não faz parte do .NET 3.5 SP1 nem do .NET 4.0; foi restrito a IEnumerable <DataRows> e não funciona para IEnumerable <T> - bit.ly/dL0G5
lema
26

Para executar essa consulta em uma DataContextclasse, faça o seguinte:

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

Sem o arquivo, as IEnumerable<DataRow>;você verá o seguinte erro de compilação:

Não é possível converter implicitamente o tipo 'System.Collections.Generic.IEnumerable' para 'System.Collections.Generic.IEnumerable'. Existe uma conversão explícita (você está perdendo um elenco?)

C1pher
fonte
22

Faça um conjunto de objetos de transferência de dados, alguns mapeadores e retorne-o por meio do .asmx.
Você nunca deve expor os objetos de banco de dados diretamente, pois uma mudança no esquema do procedimento será propagada para o consumidor de serviços da Web sem que você perceba.

Lars Mæhlum
fonte
15

Se você usar um tipo de retorno IEnumerable, poderá retornar sua variável de consulta diretamente.

Dave Ward
fonte
11

Crie um objeto de classe e retorne um list(T)da consulta.

Brian Childress
fonte
2

Se você usar IEnumerablecomo o tipo de retorno, ele retornará sua variável de consulta diretamente.

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
fonte