LIST<T> QUE NÃO RETORNA ITEM
Conforme postei em um tópico anterior, estou preenchendo um DataGridView através de um BindingSource, seguindo a recomendação do nosso amigo Kerplunk.
Acontece que ao criar um List<T> para preencher esse DataGrid, pode ser que essa List<T> não tenha nenhum item. AÃ então eu preciso saber se existe item ou não, pois dependendo do caso, vou executar tarefas diferentes.
Nesse caso:
Então, quando não existe registro na tabela que satisfaça a condição acima, estou recebendo uma List<T> cujo Count = 1, não deveria ser Count = 0 ?
E quando eu tenho apenas um registro, também recebo uma List<T> com Count = 1, aà eu não consigo fazer uma verificação para ver qual tarefa irei executar.
Alguém me dá uma luz?
Acontece que ao criar um List<T> para preencher esse DataGrid, pode ser que essa List<T> não tenha nenhum item. AÃ então eu preciso saber se existe item ou não, pois dependendo do caso, vou executar tarefas diferentes.
Nesse caso:
BindingSource dados = new BindingSource();
dados.DataSource = new BindingList<Mensagem>(new Mensagem().GetAll()).Where(x => (x.De == _user && x.Para == _contact) || (x.De == _contact && x.Para == _user)).OrderBy(x => x.Data).ThenBy(x => x.Hora);
dgvMensagens.DataSource = dados;
Então, quando não existe registro na tabela que satisfaça a condição acima, estou recebendo uma List<T> cujo Count = 1, não deveria ser Count = 0 ?
E quando eu tenho apenas um registro, também recebo uma List<T> com Count = 1, aà eu não consigo fazer uma verificação para ver qual tarefa irei executar.
Alguém me dá uma luz?
Coloque os dados selecionados em uma variável e antes de preencher o grid, verifique se a lista está vazia.
Coloque os dados selecionados em uma variável e antes de preencher o grid, verifique se a lista está vazia.
Resolvi dessa maneira, não sei se está correto, Kerplunk, você poderia me dizer? Ou tem outra forma de se fazer?
List<Mensagem> mensagens = new Mensagem().GetAll().FindAll(x => (x.De == _user && x.Para == _contact) || (x.De == _contact && x.Para == _user));
if (conversas.Count == 0)
{
return;
}
BindingSource dados = new BindingSource();
dados.DataSource = new BindingList<Mensagem>(new Mensagem().GetAll()).Where(x => (x.De == _user && x.Para == _contact) || (x.De == _contact && x.Para == _user)).OrderBy(x => x.Data).ThenBy(x => x.Hora);
dgvMensagens.DataSource = dados;
Tente assim pra ver:
List<Mensagem> mensagens = new Mensagem().GetAll().Where(x => (x.De == _user && x.Para == _contact) || (x.De == _contact && x.Para == _user)).OrderBy(x => x.Data).ThenBy(x => x.Hora);
if (mensagens != null) //Corrigido pelo Kerplunk no tópico abaixo.
{
BindingSource dados = new BindingSource();
dados.DataSource = mensagens;
dgvMensagens.DataSource = dados;
}
Este método GetAll, deveria retornar null, caso nenhum Ãtem seja encontrado, então o melhor é testar se ele é null e não se ele tem algo:
if (mensagens == null)
return;
Kerplunk, se eu fizer como você disse, nessa condição if(mensagens==null), o Visual Studio pula essa condição. Fazendo com if(mensagens.Count==0) aà funciona.
Tudo bem, eu consegui assim mesmo.
Agora eu só queria entender uma coisa: se eu usar assim:
o VS acusa um erro:
Error CS0266 Cannot implicitly convert type [ô]System.Collections.Generic.IEnumerable<Sender.Conversa>[ô] to [ô]System.Collections.Generic.List<Sender.Conversa>[ô]. An explicit conversion exists (are you missing a cast?)
mas se ao invés de usar Where eu usar o FindAll, dá certo. O que está errado? E quando devo usar um ou outro?
E outra coisa, se eu fizer como o Jaba disse:
dados.DataSource = mensagens;
também não funciona, ocorre um erro: Specified argument was out of the range of valid values.
então eu tive que fazer assim:
tive que repetir a expressão para consultar, acrescentando apenas o OrderBy porque não funciona com FindAll.
Tudo bem, eu consegui assim mesmo.
Agora eu só queria entender uma coisa: se eu usar assim:
List<Mensagem> mensagens = new Mensagem().GetAll().Where(x => (x.De == _user && x.Para == _contact) || (x.De == _contact && x.Para == _user))
o VS acusa um erro:
Error CS0266 Cannot implicitly convert type [ô]System.Collections.Generic.IEnumerable<Sender.Conversa>[ô] to [ô]System.Collections.Generic.List<Sender.Conversa>[ô]. An explicit conversion exists (are you missing a cast?)
mas se ao invés de usar Where eu usar o FindAll, dá certo. O que está errado? E quando devo usar um ou outro?
E outra coisa, se eu fizer como o Jaba disse:
dados.DataSource = mensagens;
também não funciona, ocorre um erro: Specified argument was out of the range of valid values.
então eu tive que fazer assim:
dados.DataSource = new BindingList<Conversa>(new Conversa().GetAll()).Where(x => (x.De == _user && x.Para == _contact) || (x.De == ._contact && x.Para == _user)).OrderByDescending(x => x.Data).ThenByDescending(x => x.Hora);
tive que repetir a expressão para consultar, acrescentando apenas o OrderBy porque não funciona com FindAll.
Primeiramente, vamos entender o que você está fazendo:
Em uma única chamada, você está buscando dados do banco no método GetAll, que assim que executado, será filtrado novamente com o método Where e os parâmetros que você usou. Caso GetAll não tenha retorno(não sei como está seu método, mas presumo que retorne null), o método Where também vai retornar null. Sabendo que null não pode ser instanciado, no fim das contas seu comando seria:
E isso é uma operação ilegal. Como resolver isso? Você só deveria usar comandos encadeados, quando tem certeza de que algo seja retornado. Quando não for o caso, o melhor é separar:
Repare também o método [Ô]ToList()[Ô] no final. Ele garante a conversão do retorno do método Where, seja convertido para List<Mensagem> que é um IEnumerable, evitando o erro que você está tendo.
Em uma única chamada, você está buscando dados do banco no método GetAll, que assim que executado, será filtrado novamente com o método Where e os parâmetros que você usou. Caso GetAll não tenha retorno(não sei como está seu método, mas presumo que retorne null), o método Where também vai retornar null. Sabendo que null não pode ser instanciado, no fim das contas seu comando seria:
List<Mensagem> mensagens = new null;
E isso é uma operação ilegal. Como resolver isso? Você só deveria usar comandos encadeados, quando tem certeza de que algo seja retornado. Quando não for o caso, o melhor é separar:
List<Mensagem> mensagens = new Mensagem().GetAll();
if (mensagens != null)
{
mensagens = mensagens..Where(x => (x.De == _user && x.Para == _contact) || (x.De == _contact && x.Para == _user)).ToList();
}
Repare também o método [Ô]ToList()[Ô] no final. Ele garante a conversão do retorno do método Where, seja convertido para List<Mensagem> que é um IEnumerable, evitando o erro que você está tendo.
Valeu, Kerp, muito obrigado novamente.
Assim que tiver um tempinho vou analisar melhor o meu código.
Assim que tiver um tempinho vou analisar melhor o meu código.
Acho que estou entendendo melhor [Ô]essa coisa[Ô] agora. Graças à sua paciência.
Obrigado e até mais.
Obrigado e até mais.
E eis que surge mais uma pequena dúvida. E agora quem poderá me ajudar????
Kerplunk, não vai me xingar, hein? Sei que estou fazendo muitas perguntas ultimamente, mas quando entender melhor tudo isso, já não vou ter mais tantas dúvidas.
Bom, seguindo seu conselho, Kerplunk, criei uma propriedade [Ô]Check[Ô] no objeto Mensagem. Quando vou excluir alguns registros, apenas torno a coluna check visÃvel.
AÃ para excluir os registros, seria algo assim, correto?:
Só que a linha colorida fica sublinhada, com a mesma mensagem de erro que eu poste antes: Error CS0266
E agora onde estou errando?
Kerplunk, não vai me xingar, hein? Sei que estou fazendo muitas perguntas ultimamente, mas quando entender melhor tudo isso, já não vou ter mais tantas dúvidas.
Bom, seguindo seu conselho, Kerplunk, criei uma propriedade [Ô]Check[Ô] no objeto Mensagem. Quando vou excluir alguns registros, apenas torno a coluna check visÃvel.
AÃ para excluir os registros, seria algo assim, correto?:
List<Mensagem> registros = ((List<Mensagem>)dgvMensagens.DataSource).Where(x => x.Check == true);
registros.ForEach(x => x.Delete());
Só que a linha colorida fica sublinhada, com a mesma mensagem de erro que eu poste antes: Error CS0266
E agora onde estou errando?
Tópico encerrado , respostas não são mais permitidas