Curso Windows Phone – Banco de dados local (Local Database)

Olá pessoal, tudo bom?

O uso de banco de dados local em apps para Windows Phone requer que você crie classes, dentro do seu projeto ou referenciadas a partir dele, que farão a representação dos dados e suas respectivas associações. Para persistir os dados do aplicativo, o framework do .NET precisará criar um arquivo do SQL Server Compact Edition (.sdf) para a sua aplicação, de acordo com o diagrama de classes que você definiu para representação e mapeamento dos dados (objeto-relacional).

A manipulação dos dados, operações de insert, update, delete e seleção devem ser realizadas exclusivamente via classes do Entity Framework e LINQ, portanto, é recomendável que você compreenda esses dois conceitos antes de pensar em desenvolver apps para Windows Phone que precisarão de recursos relacionados ao acesso e manipulação de dados locais.

Para exemplificar esse post, demonstrarei como criar uma simples aplicação que gerencia uma lista de tarefas a serem realizadas e, para tanto, começo demonstrando a classe que fará o mapeamento dos dados para o banco de dados. Vamos a ela:

...
...
namespace ExemploBD
{
 [Table(Name="Tarefas")]
 public class Tarefa
 {
 private int _id;

 [Column(Name="Id", IsPrimaryKey=true, IsDbGenerated=true, CanBeNull=false, AutoSync=AutoSync.OnInsert)]
 public int Id
 {
 get { return _id; }
 set { _id = value; }
 }

 private string _descricao;

 [Column(Name="Descricao", CanBeNull=false)]
 public string Descricao
 {
 get { return _descricao; }
 set { _descricao = value; }
 }

 private bool _realizada;

 [Column(Name="Realizada", CanBeNull=false)]
 public bool Realizada
 {
 get { return _realizada; }
 set { _realizada = value; }
 }

 public IEnumerable ObtemTarefas()
 {
 DAOTarefa daoTarefa = new DAOTarefa();
 return daoTarefa.ObtemTarefas();
 }

 public bool Gravar()
 {
 DAOTarefa daoTarefa = new DAOTarefa();
 return daoTarefa.Gravar(this);
 }

 public bool Excluir()
 {
 DAOTarefa daoTarefa = new DAOTarefa();
 return daoTarefa.Excluir(this);
 }

 public bool Realizado()
 {
 DAOTarefa daoTarefa = new DAOTarefa();
 return daoTarefa.Realizado(this);
 }
 }
}

Repare que no código acima, o nome da classe foi “marcado” como sendo o nome de uma tabela que será criada no banco de dados e que o nome das propriedades também foram identificados como colunas dessa futura tabela. Também já foram adicionados métodos que irão gerenciar as ações dessa classe, porém, como você deve ter percebido a codificação dos métodos foi realizada em uma outra classe de nome DAOTarefa. Veja a codificação abaixo:

...
...
namespace ExemploBD
{
  public class DAOTarefa
  {
    public IEnumerable ObtemTarefas()
    {
      List dados = new List();
      using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
      {
        dados = (from tarefa in db.Tarefas orderby tarefa.Descricao select tarefa).ToList();
      }
      return dados;
    }

    public bool Gravar(Tarefa novaTarefa)
    {
      try
      {
        using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
        {
          db.Tarefas.InsertOnSubmit(novaTarefa);
          db.SubmitChanges();
        }
        return true;
      }
      catch (Exception)
      {
        return false;
      }
    }

    public bool Excluir(Tarefa tarefa)
    {
      try
      {
        using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
        {
          var excluir = db.Tarefas.Where(t => t.Id == tarefa.Id).First();
          db.Tarefas.DeleteOnSubmit(excluir);
          db.SubmitChanges();
        }
        return true;
      }
      catch (Exception)
      {
        return false;
      }
    }

    public bool Realizado(Tarefa tarefa)
    {
      try
      {
        using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
        {
          Tarefa update = (from tar in db.Tarefas
                     where tar.Id == tarefa.Id
                     select tar).First();
          update.Realizada = !update.Realizada;
          db.SubmitChanges();
        }
        return true;
      }
      catch (Exception)
      {
        return false;
      }
    }
  }
}

O próximo passo é a criação de uma classe para que possamos vincular as classes que fazem o papel do objeto-relacional junto ao mapeamento do Entity Framework (DataContext). Através dessa classe é que daremos visibilidade das nossas classes/tabelas (no caso a classe “Tarefa”) para o app que estamos construindo. Veja o código abaixo:

...
...
namespace ExemploBD
{
  public class DataBaseContext : DataContext
  {
    public static string ConnectionString = "Data Source=isostore:/Infoeste.sdf";

    private Table _tarefas;

    public Table Tarefas
    {
      get
      {
        if (_tarefas == null)
        _tarefas = GetTable();

        return _tarefas;
      }
    }

    public DataBaseContext(string connectionString)
          : base(connectionString)
    {
      if (!this.DatabaseExists())
        this.CreateDatabase();
    }
  }
}

A partir de agora, devemos trabalhar a interface do aplicativo e invocar os métodos para realização das ações desejadas. Abaixo disponibilizo o código XAML que controla a interface do nosso exemplo:

...
...
<!--LayoutRoot is the root grid where all page content is placed-->

<!--TitlePanel contains the name of the application and page title-->

<!--ContentPanel - place additional content here-->
<StackPanel Margin="12,0,12,0" Grid.Row="1">
  <ListBox Height="Auto" x:Name="toDoList" Width="460" MaxHeight="510">
   <ListBox.ItemTemplate>
     <DataTemplate>
       <StackPanel Orientation="Horizontal" Height="70">
         <CheckBox Name="ToDo" Height="Auto" Content="{Binding Todo}" IsChecked="{Binding IsComplete}" Checked="ToDo_Checked" Width="400" Unchecked="ToDo_Unchecked"/>
         <Image Source="/Imagens/trash.png" Tap="Image_Tap" Height="40" />
       </StackPanel>
     </DataTemplate>
   </ListBox.ItemTemplate>
 </ListBox>

 <toolkit:PhoneTextBox x:Name="txtToDo" Hint="Adicione uma tarefa aqui..."
                       ActionIcon="/Imagens/add.png"
                       ActionIconTapped="txtToDo_ActionIconTapped"
                       DisplayedMaxLength="30" LengthIndicatorVisible="True"
                       MaxLength="30"/>
</StackPanel>

...
...

Agora, vamos ao código C# vinculado ao condigo XAML exposto acima:

...
...
namespace ExemploBD
{
  public partial class Database : PhoneApplicationPage
  {
    public Database()
    {
      InitializeComponent();

      AtualizarTarefas();
    }

    private void AtualizarTarefas()
    {
      Tarefa objTarefa = new Tarefa();
      toDoList.ItemsSource = objTarefa.ObtemTarefas();
    }

    private void txtToDo_ActionIconTapped(object sender, EventArgs e)
    {
      Tarefa novaTarefa = new Tarefa
      {
        Descricao = txtToDo.Text,
        Realizada = false
      };
      novaTarefa.Gravar();

      txtToDo.Text = string.Empty;
      AtualizarTarefas();
    }

    private void Image_Tap(object sender, System.Windows.Input.GestureEventArgs e)
    {
      var t = sender as Image;
      if (t != null)
      {
        Tarefa tarefa = t.DataContext as Tarefa;
        tarefa.Excluir();
        AtualizarTarefas();
      }
    }

    private void ToDo_Click(object sender, RoutedEventArgs e)
    {
      var t = sender as CheckBox;
      if (t != null)
      {
        Tarefa tarefa = t.DataContext as Tarefa;
        tarefa.Realizado();
        AtualizarTarefas();
      }
    }
  }
}

Bem pessoal, é isso!
Caso queiram mais detalhes sobre o assunto, façam o download do projeto onde eu fiz a implementação do exemplo que foi utilizado para escrever este post.

 Download do projeto Windows Phone

Grande abraço,
Eduardo Henrique Rizo

[twitter-follow screen_name=’eduardorizo’ show_count=’yes’]

Post relacionado:

Curso Windows Phone – Tópicos

82 comentários em “Curso Windows Phone – Banco de dados local (Local Database)”

  1. Pingback: Curso Windows Phone – Tópicos « Blog do Eduardo H. Rizo

  2. Ola muito bom seu post me ajudou muito ,queria pedir se vc tem tambem algum artigo para acesso remoto ao banco tenho um banco no local web q eu queria buscar informação de la e trazer para minha aplicação win phone .obrigado

    1. Olá Heitor, tudo bom?
      Nesse caso é necessário que você tenha algum WebService que tenha as regras de negócio que você precisa para sua aplicação no Windows Phone, dessa forma, na tua aplicação WP você faz as chamadas aos métodos do webservice e dessa forma consegue tanto gravar quanto consultar informações no BD remoto.

      Eu ainda não disponibilizei nenhum post sobre esse assunto, mas em breve o farei.

      Grande abraço,
      Eduardo

  3. Olá adorei o post, bem tenho um aplicativo para ser desenvolvido que seria vendas externas e gostaria de saber se tem algum exemplo ou algum post que eu possa estudar.

    Cenario.

    Vendedor com o Celular efetuando pedido e enviando para uma central processar e retirar estes pedidos, e recebendo o estoque, a minha duvida seria como fazer isso se eu carrego isso em um banco local ou caso seja possivel ler um banco na web, não sei gostaria de uma ajuda sua que vejo que tem bastante conhecimento.

  4. Oi Eduardo, sei que a pergunta não é referente ao post, mais tenho uma dúvida…
    em .Net C# eu uso Sessions para guardar valores e recupera – los depois, existe algo parecido no windows phone?

  5. Só houve um erro nesse post: Porque encapsular a DAL no modelo Poco da classe ??? ai perdeu a referencia de Design Patterns!

    1. Olá, tudo bom?
      Desculpe, mas creio não ter entendido seu ponto de vista. Poderia explicar melhor ou sugerir como poderia ser?

      PS: Eu não tive intenção de utilizar POCO nesse exemplo.

      Abraços,
      Eduardo

      1. Caro Eduardo H. Rizo, a intenção de usar os métodos gravar, excluir e realizado, foi nesse ponto que ficou fora do padrão. Inclusive é uma camada de persistência, então a classe deveria ser feita separada desses métodos e ai utilizar setando a classe DAOTarefa. Achei estranho pelo fato de ter a DAOTarefa para fazer as manipulações de alteração, exclusão, inserção, deleção e afins.
        Não me leve a mau só foi uma observação …

  6. Pingback: Curso Windows Phone: Exemplo de binding usando Listbox | Blog do Eduardo H. Rizo

  7. Bem legal Eduardo, parabéns! Quando puder posta alguma coisa como, por exemplo: atualização de uma tabela em banco de dados local via webservice ou outro meio. Abraços!

  8. Boa tarde Eduardo H. Rizo,

    Gostaria de saber como faço para obter os dados armazenados no banco de dados e poder manipular esses dados, ou seja, editá-los.

    1. Olá, tudo bom?
      No caso o banco de dados está na própria APP do WP, ou seja, armazenado no próprio aparelho ou remoto?
      Se sua resposta for remoto, você pode fazer isso via webservices, WCF, chamadas REST com retorno JSON ou XML.

  9. Aqui você demostra o SQL server né ?

    Mas tem outro jeito de se fazer este banco de dados e depois de criado Com qual ferramenta por exemplo eu inseriria dados no banco ?

    Como se usaria talvez um SQLLite para WP ?

    Grato desde já pelas respostas

    1. Ewerton, esse tipo de situação não existe para o WP.
      Você até pode criar um BD usando SQLLite e depois usar uma outra ferramenta chamada SQLMetal para gerar as classes que irão fazer o papel de mapeamento objeto relacional (entidades), mas você não tem uma ferramenta tipo um SQL Browser…

  10. O armazenamento está no próprio App sim. Eu usei seu exemplo como base para o meu, mas estou encontrando dificuldades para poder manipular os dados.
    Obrigado, Att.

    1. Boa noite Ferreira,

      Cara é bem simples usando o linq, quando você criou a tabela de ex:

      public Table Tarefas
      {
      get
      {
      if (_tarefas == null)
      _tarefas = GetTable();

      return _tarefas;
      }
      }

      no momento que vc instância seu objeto:

      using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
      {
      Tarefa update = (from tar in db.Tarefas
      where tar.Id == tarefa.Id
      select tar).First();
      update.Realizada = !update.Realizada;
      db.SubmitChanges();
      }

      da tanto pra vc fazer assim:

      using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
      {
      db.Tarefas.ToList(); ou uma expressão lambida, ou da forma que esta no exemplo

      que é o select na linguagem do linq,um select simples na tabela tarefas seria assim:

      var teste = (from c in db.Tarefas select c).ToList();
      se quiser colocar where é bem simples tbm
      var teste = (from c in db.Tarefas where c.ID == 1 select c).ToList();

      assim por diante…
      }

      qualqer dúvida estamos ai 🙂

  11. Olá Marcos Vinicius, até aonde você passo eu estou conseguindo fazer. O que eu não estou conseguindo é pegar a coluna descrição, por exemplo, e mudar o que eu escrevi, caso tenha escrito errado e salvo no banco.

  12. Criei um banco um pouco maior
    Consigo salvar MAS minha dúvida é a seguinte

    using System;
        using System.Data.Linq.Mapping;
    
        [Table(Name="tbPergunta")]
        public class Pergunta
        {
            [Column(Name = "Id_Perg", IsPrimaryKey = true, IsDbGenerated = true,
                    CanBeNull = false, AutoSync = AutoSync.OnInsert)]
            public int Id_Perg { get; set; }
    
            [Column(Name = "Descricao", CanBeNull = false)]
            public string Descricao { get; set; }
    
            [Column(Name = "Nivel", CanBeNull = false)]
            public string Nivel { get; set; }
    
            [Column(Name = "Resp1", CanBeNull = false)]
            public string Resp1 { get; set; }
    
            [Column(Name = "Resp2", CanBeNull = false)]
            public string Resp2 { get; set; }
    
            [Column(Name = "Resp3", CanBeNull = false)]
            public string Resp3 { get; set; }
    
            [Column(Name = "Resp4", CanBeNull = false)]
            public string Resp4 { get; set; }
    
            [Column(Name = "N_da_Resposta", CanBeNull = false)]
            public string N_da_Resposta { get; set; }
        }
    

    Nesta tabela eu gostaria de fazer um select e pegar o resultado deste select tipo

    Eu vi na internet assim:

            private void LoadData()
            {
                this.MainListBox.Items.Clear();
    
                // Acessa itens do banco de dados
                DataControl controller = new DataControl();
                IEnumerable<Model.DataItem> itens = controller.GetDataItem();
    
                // Adiciona itens no listbox
                foreach (DataItem listItem in itens)
                {
                    this.MainListBox.Items.Add(listItem);
                }
            }
    

    Mas eu queria algo mais livre tipo

    Igual eu vi em um comentário acima

    
    ------------------>>>>> AQUI uma conexão
    using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
    {
    db.Tarefas.ToList(); ou uma expressão lambida, ou da forma que esta no exemplo
    
    que é o select na linguagem do linq,um select simples na tabela tarefas seria assim:
    
    ----------------->>>>>>> AQUI um select
    var teste = (from c in db.Tarefas select c).ToList();
    se quiser colocar where é bem simples tbm
    var teste = (from c in db.Tarefas where c.ID == 1 select c).ToList();
    --------------->>>>>>> e queria uma resposta
    

    Resumindo

    1° Conexão (não sei como faço uma conexão no meio do código)
    2° Um select tipo select * from Pergunta where ID_PERG = 2
    3° E pegar a resposta

    textbox1.tex = respostaselect.descricao;
    textbox2.tex = respostaselect.resp1;
    textbox3.tex = respostaselect.resp2;
    textbox4.tex = respostaselect.resp3;
    e assim vai

    Teria como ?
    Se precisar de saber mais sobre alguma outra parte do código para me responder me avisa!

    Grato desde já.

    1. Olá Ewerton, tudo bom?
      No próprio exemplo tem a resposta para a sua pergunta. Observe:

      • Método ObtemTarefas: Nele crio um objeto da classe DAOTarefa e então instancio um objeto da classe DbContext, que nesse caso é a responsável pela conexão
      • No próprio método ObtemTarefas há um exemplo da criação do contexto e uma consulta Linq que retorna os dados desejados
      • Por fim repare os dois últimos trechos de código, onde no primeiro (XAML) faço binding e no segundo a chamada do método ObtemTarefas e coloco o seu retorno como resultado para o ItemSource do listbox

      OK?

      Abraços,
      Eduardo

      1. Ainda tenho dúvida, Mas qualquer coisa eu não conseguir irei fazer o seu exemplo novamente.

        Pois o meu tá assim para salvar

        private void SavePergunta(string Descricao, string Nivel, string Resp1, string Resp2, string Resp3, string Resp4, string NResp)
                {
                    Pergunta newPerg = null;
        
                    newPerg = new Pergunta();
        
                    newPerg.Descricao = Descricao;
                    newPerg.Nivel = Nivel;
                    newPerg.Resp1 = Resp1;
                    newPerg.Resp2 = Resp2;
                    newPerg.Resp3 = Resp3;
                    newPerg.Resp4 = Resp4;
                    newPerg.N_da_Resposta = NResp;
        
                    // Salva os dados no banco de dados
                    DataControl controller = new DataControl();
                    controller.Save(newPerg);
        
                    // Carrega os dados na tela
                    LoadData();
                }
        

        Minha DAO está assim em partes

        public class DAOProvider
            {
                public static void CreateDataBase()
                {
                    using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
                    {
                        if (!db.DatabaseExists())
                        {
                            db.CreateDatabase();
                        }
                    }
                }
        
                public static IEnumerable<Model.Pergunta> GetDataItems()
                {
                    List<Model.Pergunta> returnValue = null;
        
                    returnValue = new List<Model.Pergunta>();
        
                    using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
                    {
                        var query = db.Perguntas.OrderBy(d => d.Id_Perg);
        
                        foreach (Model.Pergunta item in query)
                        {
                            returnValue.Add(item);
                        }
                    }
        
                    return returnValue;
                }
        
                internal static void Save(Model.Pergunta newItem)
                {
                    using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
                    {
                        db.Perguntas.InsertOnSubmit(newItem);
        
                        db.SubmitChanges();
                    }
                }
        

        Este getDataItems funcionaria como o seu busca tarefa correto
        Eu ainda continuo com duas dúvidas:
        – Como chamar este método assim como eu chamei o de salvar pois Eu só quero uma resposta string (Mas todo mundo na internet só mostra com um list)
        – E como criaria um metodo parecido que retornaria só UMA resposta
        Exemplo:

        string Model.Pergunta returnValue = null;
        
        returnValue = new Model.Pergunta();
        

        Seria +ou- assim ?

        Eu tô muito em duvida com questão no select em C# é muito diferente do que eu uso em outras ferramentas.
        Teria como você me mostra o código de como seria um select do jeito que eu falei ?

        Grato desde já, e desculpe pela amolação

  13. public class DataBaseContext : DataContext
    {
    public static string ConnectionString = “Data Source=isostore:/Infoeste.sdf”;

    private Table _tarefas;

    public Table Tarefas
    {
    get
    {
    if (_tarefas == null)
    _tarefas = GetTable();

    return _tarefas;
    }
    }

    nesse proprio exemplo o eduardo deixa fixo a connection string fixa então toda vez que vc for fazer um select no banco tera que dar o using… para vc usar select nativo com o linq, seria assim:

    db.ExecuteStoreCommand(“select * from Tarefas”); onde o db é (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString)

    ou pode ser assim:

    db.ExecuteStoreQuery(“select * from Tarefas”);
    db.ExecuteStoreQuery(“select * from Tarefas”, parametros sql);

    para pegar uma coluna só vc faz assim no select do linq:

    var teste = (from c in db.Tarefas select c.Descricao).FirstOrDefault();

    ou usando o select nativo que eu exemplifiquei acima.

    abraço cara qql dúvida posta ai.

    1. uma correção.

      ao invés de db.ExecuteStoreQuery(“select * from Tarefas”);

      seria assim:

      db.ExecuteStoreQuery<Tarefas>(“select * from Tarefas”);

      1. Eduardo o blog não aceita colocar ?

        seria db.ExecuteStoreQuery(Tarefas)(“select * from Tarefas”);

        só que ao invés de parenteses seria chaves do . , o blog acho que não deixa postar isso.

  14. cara nesse sua dao nesse cara:

    var query = db.Perguntas.OrderBy(d => d.Id_Perg);

    se vc colocar assim:

    var query = db.Perguntas.OrderBy(d => d.Id_Perg).ToList();

    vc não precisa do foreach pra add ele em uma lista. uma dica só 🙂

  15. Primeiramente obrigado a todos pela ajuda.

    Não funcionou nenhuma ai comigo.
    Mas juntou eu e meu irmão aqui e procurando aqui durante umas duas horas rapaz rs.
    Mas finalmente achamos uma página com exatamente o que eu queria, e de quebra vai me ajudar daqui em diante, assim como seu blog Eduardo.

    (não sei é permitido colocar link externo aqui no blog) Mas é o link é http://msdn.microsoft.com/pt-br/library/jj128159.aspx

    1. Olá Ewerton, que bom que conseguiu fazer o que queria.
      Quanto a links externos, sempre são bem vindos. Obrigado pela dica!

      Aproveitando, também gostaria de divulgar um outro link externo que leva para o site 101 Linq Samples. Para você que está empenhado com as questões do Linq, não deixe de conferir.

      Grande abraço.

      1. vou dá uma olhada no link.
        Consegui dá um select comum agora irei fazer select´s um pouco mais complexo, ai o link que você passou vai ajudar.

      2. Muito bom seu post, tenho uma pergunta: como posso fazer um classe de pesquisar dados e exibir ? Por que consigo salvar uma tarefa mas não consigui exibir as tarefas salvas.

        Obrigado
        Nascimento

      3. Olá Nascimento, tudo bom?

        Se você reparar, no post há um método chamado ObtemTarefas, estou replicando ele abaixo:

            public IEnumerable ObtemTarefas()
            {
              List dados = new List();
              using (DataBaseContext db = new DataBaseContext(DataBaseContext.ConnectionString))
              {
                dados = (from tarefa in db.Tarefas orderby tarefa.Descricao select tarefa).ToList();
              }
              return dados;
            }
        

        Repare que ele faz a pesquisa no BD e o retorno dos dados. Seria esse ponto que você não está conseguindo?

        Abraços,
        Eduardo H. Rizo

  16. E o código da pesquisa ficou assim:

    using (DataBaseContext context = new DataBaseContext(DataBaseContext.ConnectionString))
                {
    
                    var query = from c in context.Perguntas where c.Id_Perg == 4 select c;
                    foreach (var item in query)
                    {
                        textBox1.Text = textBox1.Text + " " + item.Descricao;
                    }
    
                    /*
                    var query = (from c in context.Perguntas select c).Take(2);
                    foreach (var item in query)
                    {
                        textBox1.Text = textBox1.Text + " " + item.Descricao;
                    }
    
                    int quant = (from c in context.Perguntas select c).Count();
                    textBox1.Text = textBox1.Text + " " + quant;
                     */
                }
    

    Para quem quiser usar.

    1. Estou fazendo um aplicativo Windows Phone 8.1 para o meu trabalho de conclusão de curso e tava quebrando a cabeça com isso. Meu código estava quase idêntico ao de cima, mas falta um detalhe. Agradeço ao blog pela publicação e ao pessoal pelos comentários, me foram bastante úteis!

      Segue meu código também: =D

      using (var banco = new BancoContext(BancoContext.ConnectionString))
      {
      var query = (from l in banco.Tblocal
      where (l.Id_local == parametro)
      select l);

      foreach (var item in query)
      {
      var latitude = item.Latitude_local;
      var longitude = item.Longitude_local;
      lat = Convert.ToDouble(latitude);
      lon = Convert.ToDouble(longitude);
      //MessageBox.Show(“Latitude = “+ latitude +”nLongitude = ” + longitude);
      }
      }

  17. Cara oq vc achou no site é exatamente o que eu te exemplifiquei:

    var teste = (from c in db.Tarefas select c).ToList();
    se quiser colocar where é bem simples tbm
    var teste = (from c in db.Tarefas where c.ID == 1 select c).ToList();

    vc só não se atentou ao que eu passei, mas tudo bem kkkkkkkkk qql dúvida posta ai que lhe ajudaremos.

    Abraço.

    1. depois que achei o exemplo que postei eu entendi

      Mas ninguém nunca tinha postado esta linha

      using (DataBaseContext context = new DataBaseContext(DataBaseContext.ConnectionString))
                  {
                  ...
      

      Sem isto NO MEIO DO CODIGO (mainpag.xaml)
      Nada dos códigos que vocês passou funciona

      E por isto eu não conseguia
      Mas valeu

      Agora eu sei usar os códigos que vocês postaram valeu

  18. olha eu de novo rs

    Mas estou com uma outra duvida
    Agora estou trabalhando com webservice
    e tenho o seguinte código

    void cliente_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
            {
                if (e.Error != null)
                    return;
    
                XDocument xml = XDocument.Parse(e.Result);
    
                var dados = xml.Elements().Where(ele => ele.Name.LocalName == "dados");
    
                var queryxml = from c in dados
                               select new PerguntaItem
                {
                    Quant = Convert.ToInt32(dados.Elements().First(ele => ele.Name.LocalName == "resultado").Value),
                    Id = Convert.ToInt32(dados.Elements().First(ele => ele.Name.LocalName == "id").Value),
                    Descricao = dados.Elements().First(ele => ele.Name.LocalName == "descricao").Value,
                    Nivel = dados.Elements().First(ele => ele.Name.LocalName == "nivel").Value,
                    Resp1 = dados.Elements().First(ele => ele.Name.LocalName == "resp1").Value,
                    Resp2 = dados.Elements().First(ele => ele.Name.LocalName == "resp2").Value,
                    Resp3 = dados.Elements().First(ele => ele.Name.LocalName == "resp3").Value,
                    Resp4 = dados.Elements().First(ele => ele.Name.LocalName == "resp4").Value,
                    N_Resp =  Convert.ToInt32(dados.Elements().First(ele => ele.Name.LocalName == "resp4").Value)
                };
    
                PerguntaItem xmlPerguntas = new PerguntaItem();
    
                SavePergunta(xmlPerguntas.Id,
                             xmlPerguntas.Descricao,
                             xmlPerguntas.Nivel,
                             xmlPerguntas.Resp1,
                             xmlPerguntas.Resp2,
                             xmlPerguntas.Resp3,
                             xmlPerguntas.Resp4,
                             xmlPerguntas.N_Resp
                            );
            }
    

    Mas acho que estou fazendo muito errado
    Mas de acordo com um outro webservice fui tentar fazer aqui, só que o outro webservice é do youtube e só joga o resultado em um listbox

    * Eu quero fazer um download de um xml –> tá ok
    * percorrer todo o xml e ir INSERINDO no banco cada resgistro

    Este “PerguntaItem” tem estas propriedades

    public int Quant { get; set; }
    public int Id { get; set; }
    public string Descricao { get; set; }
    public string Nivel { get; set; }
    public string Resp1 { get; set; }
    public string Resp2 { get; set; }
    public string Resp3 { get; set; }
    public string Resp4 { get; set; }
    public int N_Resp { get; set; }

    O que eu estou tentando tá dando errado.

    E outra dúvida como faria para pergar um só campo no XML

    exemplo

     if (e.Error != null)
                    return;
    
                XDocument xml = XDocument.Parse(e.Result);
    
                var dados = xml.Elements().Where(ele => ele.Name.LocalName == "dados");
    
                Quant = Convert.ToInt32(dados.Elements().First(ele => ele.Name.LocalName == "resultado").Value)                     <<<---
    

    A linha em destaque queria só ler um “nó” no xml
    porque este resultado (quant) só preciso ler uma vez

    grato desde já

      1. Hum… provavelmente você não deve estar tendo o retorno esperado.
        Chegou a verificar o conteúdo e o tipo do e.Result?

        Qual a mensagem de erro?

        []s
        Eduardo

      2. Não sei se entendi se é isto mesmo,
        Mas testei pelo navegador e o retorno está ok.

        Agora como verificar o tipo do e.result ?

      3. Ewerton, só para entender melhor o cenário. Você está fazendo chamadas a um webservice e ele te devolve um resultado em XML, certo?
        Se sim, o retorno geralmente é um XElement e não um XDocument. Veja o exemplo:

        var deputado = XElement.Parse((from p in e.result.Descendants("deputado")
                                                   where p.Element("idParlamentar").Value == idDeputado
                                                   select p).First().ToString());
        
      4. Que bobeira, eu acho que foi no ctrl + barra
        Realmente pode ser, assim que eu chegar em casa eu vou testar isto.

        valeu por enquanto.

      5. Muito obrigado mais uma vez

        Agora sim consegui pegar o resultado de um xml

        Só uma questão adicional rs

        para percorrer este xml (no caso um nó ou elemento deste xml)

        eu faria assim ?

        if (e.Error != null)
                        return;
        
                    XElement xml = XElement.Parse(e.Result);
        
                    var Numero_Perg = XElement.Parse((from p in xml.Descendants("resultado")
                                                      where p.Element("idParlamentar").Value == idDeputado
                                                      /*select p).First().ToString()*/);
        

        Acima uma busca em todos os elementos SEM o select first

        var query = from c in context.Perguntas where c.Id_Perg == IncID select c;
                        foreach (var item in query)
                        {
                            txtPergunt.Text = Convert.ToString(item.Id_Perg) + " - " + item.Descricao;
                            radioButtonResp1.Content = item.Resp1;
                            radioButtonResp2.Content = item.Resp2;
                            radioButtonResp3.Content = item.Resp3;
                            radioButtonResp4.Content = item.Resp4;
                            RespAtual = item.N_da_Resposta;
                        }
        

        E o percorrer seria igual percorrer informações de um banco de dados mesmo ?

        vlw e boa noite

  19. Eu acabei conseguindo percorrer mais oi menos do jeito que eu falei
    Mas estou com outra duvida
    Eu estou percorrendo assim:

    var xmlPerguntas = (from p in xml.Descendants("pergunta")
                                    /*where p.Element("idParlamentar").Value == idDeputado*/
                                    select p);
                                    foreach (var item in xmlPerguntas)
                                    {
                                        SavePergunta(xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "descricao").Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "nivel").Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp1").Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp2").Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp3").Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp4").Value,
                                                     int.Parse(xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "n_resp").Value)
                                                     );
                                        textBlockStatusPerg.Text = cont + " de " + Numero_Perg.Value;
                                        cont = cont + 1;
                                    }
    

    Mas ai para tentar solucionar um problema neste codigo acima (que é sempre pergar o mesmo registro POIS apesar de está percorrendo o XML eu estou usando o FISRT ai sempre pega o mesmo registro)

    var xmlPerguntas = (from p in xml.Descendants("pergunta")
                                    /*where p.Element("idParlamentar").Value == idDeputado*/
                                    select p);
                                    foreach (var item in xmlPerguntas)
                                    {
                                        SavePergunta(xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "descricao" + cont).Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "nivel" + cont).Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp1" + cont).Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp2" + cont).Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp3" + cont).Value,
                                                     xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp4" + cont).Value,
                                                     int.Parse(xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "n_resp" + cont).Value)
                                                     );
                                        textBlockStatusPerg.Text = cont + " de " + Numero_Perg.Value;
                                        cont = cont + 1;
                                    }
    

    Ai eu coloquei este codigo ACIMA com UM + cont (que é um int que vai concatenado) mas dá erro teria uma outra forma de se fazer isto ?

    pois pelo menos a meu entender o first + cont que eu estou tentando usar seria uma “gabiarra” pois deve ter um outro comando que posso pegar o registro atual só que eu dei um ctrl + barra e e fui tentando mas nenhum deu certo.

    grato desde já.

    1. Ewerton, se entendi bem, basta você pegar os valores do objeto “item” que você colocou no foreach, pois ele representa cada um dos elementos do resultado da tua consulta LINQ que está na lista xmlPerguntas.

      Entendeu?

      1. Não sei se vou falar certo.
        Mas com xml eu teria que criar uma class para o itens do XML ?

        Pois com o banco de dados eu criei uma classe pergunta que quando eu usei para percorrer os campos que eu criei na classe aparecia tipo:
        digito pergunta. “ctrl + barra” ai aparece as propriedades descricao resp1 resp2 etc

        Mas a do item ou o xmlPergunta eu digito e aparece como ele fosse um Xelement

        Vou confirmar quando estiver em caso
        Mas pelo menos pelo que eu estou fazendo não tõ encarando o Xelement ou xml como um banco de dados eu deveria criar uma classe então para os elementos do XML ?

      2. Seria legal você definir uma classe para representar os dados que retornarão do XML, pois dessa forma você conseguirá manipular os dados mais facilmente.
        Nesse caso, você faz a tua consulta LINQ retornar uma lista da classe que irá representar os dados. OK?

      3. Mas você poderia me ajudar a saber como eu colocaria a consulta que eu faço para se ligar a minha classe ligada?

        Classe

        namespace RioQuiz.objWebClient
        {
            public class PerguntaItem
            {
                public int Id { get; set; }
                public string Descricao { get; set; }
                public string Nivel { get; set; }
                public string Resp1 { get; set; }
                public string Resp2 { get; set; }
                public string Resp3 { get; set; }
                public string Resp4 { get; set; }
                public int N_Resp { get; set; }
            }
        }
        

        MAS eu qual momento eu tenho de instanciar a classe e como?

        int cont = 1;
        
                    if (e.Error != null)
                        return;
        
                    XElement xml = XElement.Parse(e.Result);
        
                    var Numero_Perg = XElement.Parse((from p in xml.Descendants("resultado")
                                                      /*where p.Element("idParlamentar").Value == idDeputado*/
                                                      select p).First().ToString());
        
                    if (int.Parse(Numero_Perg.Value) > 0)
                    {
                        DeletaDataBase();
                        CreateDataBase();
                    }
        
                    textBlockStatusPerg.Text = "0 de " + Numero_Perg.Value;
                    textBlockStatusPerg.Visibility = Visibility.Visible;
        
                    var xmlPerguntas = (from p in xml.Descendants("pergunta")
                                        /*where p.Element("idParlamentar").Value == idDeputado*/
                                        select p);
        
                                        foreach (var item in xmlPerguntas)
                                        {
                                            SavePergunta(xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "descricao").Value,
                                                         xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "nivel").Value,
                                                         xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp1").Value,
                                                         xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp2").Value,
                                                         xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp3").Value,
                                                         xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "resp4").Value,
                                                         int.Parse(xmlPerguntas.Elements().First(ele => ele.Name.LocalName == "n_resp").Value)
                                                         );
                                            textBlockStatusPerg.Text = cont + " de " + Numero_Perg.Value;
                                        }
        
                    textBlockStatusPerg.Visibility = Visibility.Collapsed;
        

        Pois igual ao que faço pelo banco de dados não tem como pois o item recebe os atributos de um Xelement

         var xmlPerguntas = (from p in xml.Descendants("pergunta") 

        Como eu faria usando o xml.

        grato desde já.

      4. Pense assim:

        Imagine que eu tenha uma classe “Partido” descrita da seguinte forma:

        public class Partido
        {
          public string Logo {get; set;}
          public string Sigla {get; set;}
          public string Nome {get; set;}
        }
        

        Assim eu teria uma consulta LINQ gerando uma lista dessa classe sendo feita de forma similar ao exemplo abaixo:

        var dados = (from p in result.Descendants("partido")
                    orderby p.Element("siglaPartido").Value
                    where p.Element("dataExtincao").Value == ""
                    select new Partido
                    {
                      Logo = string.Format("Imagens/Partidos/{0}.png", p.Element("siglaPartido").Value),
                      Sigla = p.Element("siglaPartido").Value,
                      Nome = p.Element("nomePartido").Value
                    }).ToList();
        

        Sendo que para mim “dados” seria uma lista da classe Partido, entendeu?

  20. Mas ai quando escrevesse dados. “ctrl + barra” não deveria aparaecer
    Logo
    Sigla
    Nome

    ou deveria aparecer as opções de XElement pois é isto que aparece no meu como fosse um xElement

      1. Finaaaalmente rsrsrs

        Pesquisando bastante e aprendendo também
        Cheguei a este link
        http://msdn.microsoft.com/pt-br/library/system.xml.linq.xelement(v=vs.110).aspx
        e aprendi bastante.

        Consegui com o seguinte código

        XElement perguntas = xml.Descendants("perguntas").First();
        
                    foreach(XElement a in perguntas.Nodes())
                    {
                        SavePergunta(a.Element("descricao").Value,
                        a.Element("nivel").Value,
                        a.Element("resp1").Value,
                        a.Element("resp2").Value,
                        a.Element("resp3").Value,
                        a.Element("resp4").Value,
                        Convert.ToInt32(a.Element("n_resp").Value)
                        );
                    };
        

        Valeu ai pelas respostas
        e fica ai a dica

  21. Não estou conseguindo conseguindo converter para int para poder realizar uma operação. Segue abaixo o trecho do código.

    using (DataBase db = new DataBase(DataBase.ConnectionString))
    {
    var teste = (from tar in db.Produtos
    where tar.NomeProduto == cb.Content.ToString()
    select tar).Single();
    teste.Quantidade = Convert.ToInt32(teste.Quantidade) – 1;

    db.SubmitChanges();

    Alguém tem uma solução??

  22. Eduardo, eu gostaria de saber como eu crio minha tabela já com dados preenchidos. Pois eu queria utilizar o seguinte trecho de código:

    if (radioButAvista.IsChecked == true)
    {
    novaVenda.Pag = “À vista”;
    using (DBPag db = new DBPag(DBPag.ConnectionString))
    {
    var dados = (from tar in db.Pags where tar.Id == 0 select tar).Single();

    dados.Quantav++;

    db.SubmitChanges();
    }

    }

    Só que da erro, pois não há nenhum elemento na tabela, eu eu não gostaria de utilizar o método Gravar, pois cria novos dados.

    Ou então, como faço para utilizar o método Gravar, somente quando a tabela estiver vazia.

    1. Olá Felipe, tudo bom?
      Eu tenho uma situação parecida com a sua em uma das minhas APPs e então resolvi da seguinte forma:

      No arquivo principal da aplicação (MainPage.xaml.cs) eu tenho um método que verifica a existência de dados na tabela local e, caso não encontre, eu então adiciono no contexto do Entity Framework os dados que desejo, assim na primeira vez a APP é executa os dados serão adicionados na tabela e depois não precisaremos mais fazer isso. Veja o trecho de código abaixo.

      //Criar tipos de Operacoes
      private void CriarTiposOperacoes()
      {
         var dados = from Operacao op in CalculadoraDB.Operacoes
                     select op;
      
         // Execute the query and place the results into a collection.
         Operacoes = new ObservableCollection<Operacao>(dados);
      
         if (Operacoes.Count == 0)
         {
            Operacao op1 = new Operacao { Descricao = "Financiamento com prestações fixas" };
            Operacao op2 = new Operacao();
            op2.Descricao = "Aplicações com depósitos regulares";
            Operacao op3 = new Operacao { Descricao = "Valor futuro de um capital" };
      
            Operacoes.Add(op1);
            CalculadoraDB.Operacoes.InsertOnSubmit(op1);
      
            Operacoes.Add(op2);
            CalculadoraDB.Operacoes.InsertOnSubmit(op2);
      
            Operacoes.Add(op3);
            CalculadoraDB.Operacoes.InsertOnSubmit(op3);
      
            CalculadoraDB.SubmitChanges();
         }
      }
      
  23. Comecei a utilizar o banco Sqlite no Windows Phone.

    E tenho uma dúvida a respeito de select no banco sqlite.

    /*
    List items = null;
    items = App.db.Query(“select Nome from Usuario”);
    ListBox.ItemsSource = items;
    */

    Este select comentado funciona para mostrar os dados em listbox. Ou seja, dá para mim ver se está salvando os dados no BD. E está salvando!

    MAS estou querendo fazer algo assim:
    // ————
    string Email;
    Email = App.db.Query(“select Email from Usuario”).ToString();

    MessageBox.Show(Email);
    //————-

    Tentei também assim (me passaram para tentar):
    var returnedCollection = App.db.Query(“select Email from Usuario”);
    for (int i = 0; i < returnedCollection.Count(); i++)
    {
    string email = (returnedCollection[i]).ToString();
    MessageBox.Show(email);
    }

    return;

    Mas também não funcionou só aparece BD.Usuario no MessageBox

    Você poderia me ajudar?
    Grato desde já.

    1. Pelo que entendo você está tendo como retorno um conjunto de objetos da classe Usuario, por isso, o MessageBox exibe BD.Usuario.
      Já tentou usar assim: MessageBox.Show(email.Nome)? Onde “Nome” seria a propriedade que representa o nome do usuário?

      Abraços,
      Eduardo H. Rizo

      1. Me lembrando aqui eu acho que sim! Foi uma das primeira coisas que tentei.

        Mas posso conferir e depois de dá um retorno.
        (O meu notebook não está agora comigo)

      2. Quase que ficou igual você me falou. Mas com o email não deu. Juntei os dois códigos e deu certo.

        Consegui assim:

        var returnedCollection = App.db.Query(“select Email from Usuario”);
        for (int i = 0; i < returnedCollection.Count(); i++)
        {
        MessageBox.Show(returnedCollection[0].Email.ToString());
        }

        Valeu pela ajuda.

  24. Eduardo,
    neste seu exemplo, como você gera as instruções, automaticamente por alguma ferramenta(lendo o banco) ou digitando, mesmo?

    [Table(Name=”Tarefas”)]
    public class Tarefa

    [Column(Name=”Id”, IsPrimaryKey=true, IsDbGenerated=true, CanBeNull=false, AutoSync=AutoSync.OnInsert)]
    public int Id
    {
    get { return _id; }
    set { _id = value; }
    }

    private string _descricao;

    [Column(Name=”Descricao”, CanBeNull=false)]
    public string Descricao
    ….

Deixe um comentário para Bruno Cancelar resposta