none
Converter uma consula LINQ para DataSet. RRS feed

  • Pergunta

  • Olá pessoal, preciso alimentar uma dataGridView com dados onde o usuário possa depois realizar inserções e alterações na grid.

    A seguinte linha funciona, porém torna a GridView ReadOnly.

                grvPonto.DataSource = (from e in query select new { DataHora = String.Concat(
                    e.dataHora.Day,"/",
                    e.dataHora.Month, "/",
                    e.dataHora.Year, " ",
                    e.dataHora.Hour, ":",
                    e.dataHora.Minute, ":",
                    e.dataHora.Second),
                    e.justificativa }).ToList();
    
    Descobri que é necessário passar um DataSet ao invés de uma query. O problema é que não estou sabendo fazer esta conversão. Tentei várias soluções nos fóruns para converter essa consulta, mas sem sucesso. Alguém poderia me ajudar?


    []´s Rodolfo Andrade

    quarta-feira, 24 de setembro de 2014 20:06

Respostas

  • Olá Rodorush,

     seu datagrid fica somente leitura porque quando utiliza o select new {} você está criando uma classe anonima, classes anonimas em C# são somente leitura, o que poderia ser feito seria criar uma classe com todas as suas propriedades ou inserir as linhas do grid na "mão"... Caso precise realmente do DataSource crie uma classe e carregue com o List<T> mesmo fica mais simples de trabalhar.

    • Marcado como Resposta Rodorush quinta-feira, 25 de setembro de 2014 17:14
    quinta-feira, 25 de setembro de 2014 10:36
  •   /// <summary>Cria uma DataTable de um tipo </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="objetos"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(IEnumerable<T> objetos)
        {
          var tipo = typeof(T);
    
          //Obtém as propriedades do tipo T
          var propriedades = tipo
            .GetProperties()
            .Where(p => !(p.PropertyType is IEnumerable))
            .ToArray();
    
          //Cria as colunas
          var colunas = propriedades
            .Select(p => new DataColumn(p.Name, p.PropertyType))
            .ToArray();
    
          //Cria as linhas
          var linhas = objetos
            .Select(o => propriedades.Select(p => p.GetValue(o, null)).ToArray())
            .ToList();
    
          //Cria a DataTable
          var dt = new DataTable(tipo.Name);
    
          //Adiciona as colunas
          dt.Columns.AddRange(colunas);
    
          //Adiciona as linhas
          linhas.ForEach(o => dt.Rows.Add(o));
    
          return dt;
        }
    


    • Editado Gustavo A. Gonçalves quinta-feira, 25 de setembro de 2014 16:17
    • Marcado como Resposta Rodorush quinta-feira, 25 de setembro de 2014 17:14
    quinta-feira, 25 de setembro de 2014 16:16

Todas as Respostas

  • Olá..

    Pelo o que eu entendi, seu objeto 'query' já é uma lista de string correto, e você quer passar estes dados para uma grid. Então seu código ficaria + - assim.

    <asp:GridView runat="server" ID="gridDados" AutoGenerateColumns="false" EmptyDataText="Dados Não encontrados" Width="100%" >
      <Columns>
        <asp:BoundField DataField="DataHora" HeaderText="Data" />
        <asp:TemplateField >
          <ItemTemplate>
            <asp:textBox runat="server" id="txtDados" />
          </ItemTemplate>
        </asp:TemplateField>
      </Columns>
    </asp:GridView>

    Seu código ficaria assim:

    List<string> dados = query.Select(q => q.dataHora.ToString("dd/MM/yyyy HH:mm")).ToList();
    
    this.gridDados.DataSource = dados;
    this.gridDados.DataBind();
    É isto que você esta tentando?

    quarta-feira, 24 de setembro de 2014 20:42
  • Olá Rodorush,

     seu datagrid fica somente leitura porque quando utiliza o select new {} você está criando uma classe anonima, classes anonimas em C# são somente leitura, o que poderia ser feito seria criar uma classe com todas as suas propriedades ou inserir as linhas do grid na "mão"... Caso precise realmente do DataSource crie uma classe e carregue com o List<T> mesmo fica mais simples de trabalhar.

    • Marcado como Resposta Rodorush quinta-feira, 25 de setembro de 2014 17:14
    quinta-feira, 25 de setembro de 2014 10:36
  • Obrigado pela resposta Daniel, tentei fazer o que o amigo sugeriu mas o DataGrid continua ReadOnly, veja se é isso?

                List<PontoAuxiliar> pontoAuxList = new List<PontoAuxiliar>();
                PontoAuxiliar pontoAux = new PontoAuxiliar();
                
                var lista = (from e in query select new { e.dataHora, e.justificativa }).ToList();
    
                foreach(var linha in lista)
                {
                    pontoAux.dataHora = linha.dataHora;
                    pontoAux.justificativa = linha.justificativa;
                    pontoAuxList.Add(pontoAux);
                }
                
                grvPonto.DataSource = pontoAuxList;
    

    Criei a classe (PontoAuxiliar) que contém somente os dois campos que preciso no DataGrid. Criei também uma variável para armazenar uma lista desta classe (pontoAuxList).

    Percorro minha consulta passando cada dado da lista anonima para a lista PontoAuxiliar e em seguida alimento o DataSource com esta lista de PontoAuxiliar.


    []´s Rodolfo Andrade

    quinta-feira, 25 de setembro de 2014 14:50
  •   /// <summary>Cria uma DataTable de um tipo </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="objetos"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(IEnumerable<T> objetos)
        {
          var tipo = typeof(T);
    
          //Obtém as propriedades do tipo T
          var propriedades = tipo
            .GetProperties()
            .Where(p => !(p.PropertyType is IEnumerable))
            .ToArray();
    
          //Cria as colunas
          var colunas = propriedades
            .Select(p => new DataColumn(p.Name, p.PropertyType))
            .ToArray();
    
          //Cria as linhas
          var linhas = objetos
            .Select(o => propriedades.Select(p => p.GetValue(o, null)).ToArray())
            .ToList();
    
          //Cria a DataTable
          var dt = new DataTable(tipo.Name);
    
          //Adiciona as colunas
          dt.Columns.AddRange(colunas);
    
          //Adiciona as linhas
          linhas.ForEach(o => dt.Rows.Add(o));
    
          return dt;
        }
    


    • Editado Gustavo A. Gonçalves quinta-feira, 25 de setembro de 2014 16:17
    • Marcado como Resposta Rodorush quinta-feira, 25 de setembro de 2014 17:14
    quinta-feira, 25 de setembro de 2014 16:16
  • Pessoal, resolvido! Era isso mesmo que eu precisava. Juntando a solução do Daniel Brito de trazer o tipo anônimo para um tipo conhecido, com a classe de conversão do Gustavo deu certo e o DataGrid passou a ser editável. Muitíssimo obrigado aos amigos Demetrius, Daniel e Gustavo por terem desprendido esta atenção comigo. Sucesso e todo de bom!

    []´s Rodolfo Andrade

    quinta-feira, 25 de setembro de 2014 17:13