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

Marcado com: , , , , , , , ,
79 comentários sobre “Curso Windows Phone – Banco de dados local (Local Database)
  1. heitor oliveira disse:

    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

    • 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

  2. charbel disse:

    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.

  3. Josias Valiengo disse:

    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?

  4. Sérgio Silva disse:

    Olá Eduardo muito bom o seu post, vai me ajudar nos estudos com Windows Phone e Base de Dados.

  5. Jose Manson disse:

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

    • 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

      • Jose Manson disse:

        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 …

      • Sim, muito bem observado Jose Manson. Agradeço pela observação e isso com certeza irá contribuir mais com o nosso Blog.

        Grande abraço…

  6. Alex disse:

    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!

  7. Ferreira disse:

    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.

    • 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.

  8. Ewerton disse:

    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

    • 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…

  9. Ferreira disse:

    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.

    • Marcos Vinicius disse:

      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 🙂

    • Marcos Vinicius disse:

      para usar o sqlite tem esse exemplo da nokia qye é bom..

      http://developer.nokia.com/Community/Wiki/Como_usar_o_SQLite_no_Windows_Phone

  10. Ferreira disse:

    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.

  11. Ewerton disse:

    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á.

    • 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

      • Ewerton disse:

        Olá tudo bem,

        Vou fazer aqui e vou te retornar, se eu consegui ou se falhei rs

        Até daqui a pouco

      • Ewerton disse:

        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

      • Então, mas você quer o exemplo do select usando LINQ?

        []s
        Eduardo

  12. Marcos Vinicius disse:

    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.

    • Marcos Vinicius disse:

      uma correção.

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

      seria assim:

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

      • Marcos Vinicius disse:

        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.

      • Blz, eu já arrumei isso…

        Obrigado.

  13. Marcos Vinicius disse:

    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ó 🙂

  14. Ewerton disse:

    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

    • 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.

      • Ewerton disse:

        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.

      • Nascimento disse:

        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

      • ehrizo disse:

        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

  15. Ewerton disse:

    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.

    • 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);
      }
      }

  16. Marcos Vinicius disse:

    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.

    • Ewerton disse:

      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

  17. Ewerton disse:

    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á

    • Ewerton, tudo bom?
      Qual é o tipo de erro que você está recebendo em relação à primeira parte do código que você postou?

      []s
      Eduardo

      • Ewerton disse:

        Não passa daqui

        XDocument xml = XDocument.Parse(e.Result);
        
      • 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

      • Ewerton disse:

        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 ?

      • 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());
        
      • Ewerton disse:

        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.

      • Ewerton disse:

        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

  18. Ewerton disse:

    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á.

    • 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?

      • Ewerton disse:

        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 ?

      • 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?

      • Ewerton disse:

        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á.

      • 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?

  19. Ewerton disse:

    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

  20. Bruno disse:

    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??

  21. Felipe disse:

    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.

    • 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();
         }
      }
      
  22. Felipe disse:

    Muito Obrigado Eduardo, deu certo aqui.
    Parabéns pelo blog. Muito útil mesmo. Abraços

  23. Ewerton disse:

    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á.

    • 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

      • Ewerton disse:

        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)

      • Ewerton disse:

        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
    ….

  25. Rudy Huyn brasileiro rsrs :p simplesmente é o melhor desenvolvedor de Windows Phone brasileiro (ao menos um que compartilha conhecimento) parabéns, virei teu fã

  26. Boa tarde Eduardo H. Rizo,

    Cara se no caso eu incluir novas tabelas no meu banco, ou seja criar novos objetos mapeados com o linq, como eu faço pra atualizar o Banco de Dados do usuário ?

  27. Olá, tudo bom?
    Eu encontrei dois links que podem te ajudar, são eles:

    e http://msdn.microsoft.com/pt-br/library/jj856238.aspx

  28. Vou dar uma olhada, muito obrigado. Abraço.

2 Pings/Trackbacks para "Curso Windows Phone – Banco de dados local (Local Database)"
  1. […] Curso Windows Phone – Banco de dados local […]

  2. […] Curso Windows Phone – Banco de dados local (Local Database) […]

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

*