Funcionalidades de Acesso a Dados no 'Mango'

1,558 views

Published on

Apresentação sobre as funcionalidades de acesso a dados na nova versão do Windows Phone 7, conhecida por "Mango", que fiz no evento WP7 "Mango" Dev Hub.

Código-fonte das demonstrações:
https://github.com/CaioProiete/WP7MangoDevHub2011-DataAccess

1 Comment
0 Likes
Statistics
Notes
  • Be the first to like this

No Downloads
Views
Total views
1,558
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
1
Likes
0
Embeds 0
No embeds

No notes for slide

Funcionalidades de Acesso a Dados no 'Mango'

  1. 1. Funcionalidades de Acesso a Dados no ‘Mango’<br />CaioProiete<br />Formador @ CicloFormação<br />Organizador @ ComunidadeNetPonto<br />
  2. 2. CaioProiete<br />+10 anos de experiênciaprofissionalem TI<br />Consultor da Novabase<br />Formador da Ciclo<br />Líder da comunidadeNetPonto<br />Microsoft MVP, MCT<br />@CaioProiete<br />http://caioproiete.net<br />
  3. 3. PrincipaisNovidades<br />SQL CE DB<br />Criação e utilização de bases de dados (!)<br />Consultasaoscontactos e compromissos<br />Consultas a serviçosOData (Open Data Protocol)<br />
  4. 4. LINQ to Everything<br />LINQ<br />Objects<br />XML<br />7<br />
  5. 5. LINQ to Everything<br />LINQ<br />Objects<br />XML<br />SQL<br />User Data<br />OData<br />7<br />Mango<br />
  6. 6. Agenda<br />LINQ to SQL<br />LINQ to User Data<br />VisãoGeral<br />Arquitectura<br />Desenvolvimento “Code-first”<br />Detalhes de Implementação<br />Consultas<br />Inserir,alterar,e apagarregistos<br />Actualizaçõesna base de dados<br />Performance e boas práticas<br />VisãoGeral<br />Consentimento do utilizador<br />Tipos de contassuporsuportados<br />Detalhes de Implementação<br />Consultasaoscontactos<br />Consultasaoscompromissos<br />Performance e boas práticas<br />
  7. 7. EstruturaComplexa<br />Diversosrelacionamentos e restrições<br />Exemplo: Shopping List<br />7 tabelas<br />5 chavesestrangeiras<br />Algumascentenas de registos<br />
  8. 8. Dados de Referência<br />Grandesquantidades de informaçãoestática<br />Exemplo: dicionário, tradutor<br />3 tabelas<br />1 tabela com 500 mil registos<br />
  9. 9. Web Service Cache<br />Cloud Service<br />Obtém as informaçõesatravés de um serviçonacloud<br />Guardaos dados localmenteparaconsultaoff-line<br />Combina com dados específicos do utilizador<br />Windows Phone<br />Service Cache<br />User Data<br />
  10. 10. Dados do Utilizador<br />FiltrarContactos<br />Aniversários no próximomês<br />ConsultartodososCompromissos<br />Encontrar data/horadisponívelparaumareunião<br />Filtro<br />
  11. 11. Demonstração<br />Mobile Wine Cellar<br />Permitegerirsuacolecção de vinhos no telefone<br />Obtém dados do site wine.com via serviçoOData<br />Guardainformações do utilizadorem base de dados local<br />Consultacontactos e compromissosaoplanearprova de vinhos<br />
  12. 12. Base de Dados<br />
  13. 13. Armazenamento Local de Dados<br />Aplicaçõesguardamdados privados no Isolated Storage<br /><ul><li>Definições e propriedades no dicionário
  14. 14. Dados nãoestruturadosemficheiros
  15. 15. Dados estruturadosem bases de dados</li></ul>Pasta Raiz da Aplicação<br />Install<br />Package Manager<br />Cria pasta raiz<br />isoladapara a aplicação<br />Pasta de Dados da Aplicação<br />Cria/Manipula<br />ficheiros e definições<br />Aplicação<br />WP7 Isolated Storage APIs<br />Application<br />Settings File<br />Application<br />Files<br />
  16. 16. Armazenamento Local de Dados<br />Aplicaçõesguardamdados privados no Isolated Storage<br /><ul><li>Definições e propriedades no dicionário
  17. 17. Dados nãoestruturadosemficheiros
  18. 18. Dados estruturadosem bases de dados</li></ul>Pasta Raiz da Aplicação<br />Install<br />Package Manager<br />Cria pasta raiz<br />isoladapara a aplicação<br />Pasta de Dados da Aplicação<br />Cria/Manipula<br />ficheiros e definições<br />Aplicação<br />WP7 Isolated Storage APIs<br />DB<br />Application<br />Settings File<br />Application<br />Files<br />Database file<br />
  19. 19. Armazenamento Local de Dados<br />Aplicaçõesguardamdados privados no Isolated Storage<br /><ul><li>Definições e propriedades no dicionário
  20. 20. Dados nãoestruturadosemficheiros
  21. 21. Dados estruturadosem bases de dados</li></ul>Pasta Raiz da Aplicação<br />Install<br />Package Manager<br />Cria pasta raiz<br />isoladapara a aplicação<br />DB<br />Database<br />File (read-only)<br />Pasta de Dados da Aplicação<br />Cria/Manipula<br />ficheiros e definições<br />Aplicação<br />WP7 Isolated Storage APIs<br />DB<br />Application<br />Settings File<br />Application<br />Files<br />Database file<br />
  22. 22. Base de Dados Local<br />Base de dados não é partilhadaentre aplicações. Cadaaplicaçãoacedesomente as suaspróprias BDs<br />Tamanhomáximo de cada base de dados = 512 MB<br />Não é possívelexecutarconsultas T-SQL. Acessoaos dados apenas via LINQ to SQL<br />
  23. 23. Arquitectura<br />
  24. 24. Arquitectura<br />SuaAplicação<br />Data Context<br />Objectos<br />var query = fromw indb.Wines<br />wherew.Country== "Portugal"<br />selectw.Name;<br />
  25. 25. Arquitectura<br />SuaAplicação<br />Data Context<br />Objectos<br />var query = fromw indb.Wines<br />wherew.Country== "Portugal"<br />selectw.Name;<br />System.Data.Linq<br />Identity Management<br />Change Tracking<br />Update Processing<br />Object Materialization<br />.Call System.Linq.Queryable.Select( .Call System.Linq.Queryable.Where( .Constant(Table(Wines)), '(.Lambda #Lambda1)), '(.Lambda #Lambda2)) .Lambda #Lambda1(db.Wines $w) { $w.Country== "Portugal" } .Lambda #Lambda2(w.Country $w) { $w.Name}<br />
  26. 26. Arquitectura<br />SuaAplicação<br />Data Context<br />Objectos<br />var query = fromw indb.Wines<br />wherew.Country== "Portugal"<br />selectw.Name;<br />System.Data.Linq<br />Identity Management<br />Change Tracking<br />Update Processing<br />Object Materialization<br />.Call System.Linq.Queryable.Select( .Call System.Linq.Queryable.Where( .Constant(Table(Wines)), '(.Lambda #Lambda1)), '(.Lambda #Lambda2)) .Lambda #Lambda1(db.Wines $w) { $w.Country== "Portugal" } .Lambda #Lambda2(w.Country $w) { $w.Name}<br />select Name<br />from Wines<br />where Country = "Portugal"<br />Microsoft.Phone.Data.Internal<br /> Core ADO.NET (System.Data)<br />SQL CE DB<br />SQLCE ADO.NET Provider (System.Data.SqlServerCe)<br />
  27. 27. Desenvolvimento “Code First”<br />
  28. 28. Desenvolvimento “Code First”<br />Design time<br /><ul><li>Criar o modelo de classes: wines, varietals, vineyards, etc.
  29. 29. Decorar as classes com osatributosparapersistência dos dados</li></ul>Varietals<br />Wines<br />Vineyards<br />
  30. 30. Desenvolvimento “Code First”<br />Design time<br /><ul><li>Criar o modelo de classes: wines, varietals, vineyards, etc.
  31. 31. Decorar as classes com osatributosparapersistência dos dados</li></ul>Varietals<br />Wines<br />Vineyards<br /><ul><li>Criar o DataContextreferente a base de dados
  32. 32. Transformarmodelo de classes no ficheiro da base de dados
  33. 33. Persistir as alteraçõesna base de dados através da API</li></ul>Run time<br />
  34. 34. Desenvolvimento “Code First”<br />Design time<br /><ul><li>Criar o modelo de classes: wines, varietals, vineyards, etc.
  35. 35. Decorar as classes com osatributosparapersistência dos dados</li></ul>Varietals<br />Wines<br />Vineyards<br />WineMakers<br /><ul><li>Criar o DataContextreferente a base de dados
  36. 36. Transformarmodelo de classes no ficheiro da base de dados
  37. 37. Persistir as alteraçõesna base de dados através da API</li></ul>Run time<br />Database upgrade<br /><ul><li>Criarnovas classes com as alterações
  38. 38. Utilizar APIs de actualizaçãoparaalterar a base de dados</li></li></ul><li>Criação da Base de Dados: Exemplo<br />// Define o DataContext.<br />publicpartialclassWineDataContext: DataContext<br />{<br />publicTable<Wine> Wines;<br />publicTable<Vineyard> Vineyards;<br />publicWineDataContext(stringconnectionString) : base(connectionString) { }<br />}<br />// Define as tabelas da base de dados<br />[Table]<br />publicclassWine<br />{<br />[Column(IsPrimaryKey=true]<br />publicstringWineID{ get; set; }<br />[Column]<br />publicstringName { get; set; }<br />……<br />}<br />// Cria a base de dados no isolated storage, se nãoexistir<br />DataContextdb = newWineDataContext("isostore:/WineDB.sdf");<br />if (!db.DatabaseExists()) db.CreateDatabase();<br />
  39. 39. Consultaaos Dados: Exemplo<br />// Criaumainstância do DataContextpara a BD definidana string de conexão<br />DataContextdb = newWineDataContext("isostore:/WineDB.sdf");<br />// Obtémtodososvinhos da variedade “Merlot” existentes no stock de casa, <br />// ordenadospela data de aquisição<br />varq = from w indb.Wines<br /> wherew.Varietal.Name == "Merlot" && w.IsAtHome == true<br />orderbyw.DateAcquired<br /> select w;<br />
  40. 40. Inserts/Updates/Deletes<br />Código da suaAplicação<br />Efectuadosatravés do DataContext<br />Alteraçõessãoefectuadasprimeiro no DataContext (emmemória) e sódepoisgravadasna base de dados via SubmitChanges()<br />SubmitChanges<br />O LINQ to SQL verifica o quefoialteradoactualiza a base de dados<br />DataContext<br />DB<br />
  41. 41. Inserts/Updates/Deletes<br />Update<br />Insert<br />WinenewWine= newWine<br />{<br />WineID = 1768,<br />Name = "Windows Phone Syrah",<br />Description = "Bold and spicy"<br />};<br />db.Wines.InsertOnSubmit(newWine);<br />db.SubmitChanges();<br />Winewine= <br />(fromw indb.Wines<br /> wherew.WineID == 1768<br />select w).First();<br />wine.Description= "Hints of plum and melon";<br />db.SubmitChanges();<br />
  42. 42. Inserts/Updates/Deletes<br />Delete<br />varvineyardsToDelete= <br />fromVineyards v in db.Vineyards<br />wherev.Country== "Spain"<br />select v;<br />db.Vineyards.DeleteAllOnSubmit<br />(vineyardsToDelete);<br />db.SubmitChanges();<br />
  43. 43. Inserts/Updates/Deletes<br />Delete<br />varvineyardsToDelete= <br />fromVineyards v in db.Vineyards<br />wherev.Country== "Spain"<br />select v;<br />db.Vineyards.DeleteAllOnSubmit<br />(vineyardsToDelete);<br />db.SubmitChanges();<br />Podeocorrerumaexcepçãoaqui se osvinhosassociadosnãoforemapagadosprimeiro (foreign key constraint)<br />
  44. 44. Inserts/Updates/Deletes<br />Delete<br />varvineyardsToDelete= fromVineyards v indb.Vineyards<br /> wherev.Country== "Spain"<br />select v;<br />foreach (Vineyards v invineyardsToDelete)<br />{<br />db.Wines.DeleteAllOnSubmit(v.Wines);<br />}<br />db.Vineyards.DeleteAllOnSubmit(vineyardsToDelete);<br />db.SubmitChanges();<br />
  45. 45. Demonstração<br />Base de Dados<br />Criar base de dados<br />Consultar, inserir, alterar e apagarregistos<br />Utilizarconsultascompiladas<br />Código-fontedisponívelem:<br />https://github.com/CaioProiete/WP7MangoDevHub2011-DataAccess<br />
  46. 46. ActualizaçõesnaEstrutura da BD<br />O DatabaseSchemaUpdaterpermiteefectuaroperações simples de actualizaçãonaestrutura de bases de dadosPermiteadicionar<br />Tabelas<br />Colunas<br />Índices<br />Associações/chavesestrangeiras<br />Actualizaçõesnaestruturasãotransacionais<br />Para actualizaçõesmaiscomplexas é precisoefectuar a migração total da base de dados<br />
  47. 47. ActualizaçõesnaEstrutura da BD<br />Criauma nova instância do DatabaseSchemaUpdaterWineDataContextdbContext = newWineDataContext("isostore:/WineDB.sdf");DatabaseSchemaUpdaterdbUpdater = dbContext.CreateDatabaseSchemaUpdater();<br />Adicionauma nova tabelaassociada a classeWinemakerdbUpdater.AddTable<Winemaker>();<br />Adiciona a colunaYearEstabilishednatabelaVineyarddbUpdater.AddColumn<Vineyard>("YearEstablished");<br />Executa as actualizaçõesnaestrutura<br />dbUpdater.Execute();<br />
  48. 48. Demonstração<br />Base de Dados<br />Alteração da estrutura da base de dados<br />Código-fontedisponívelem:<br />https://github.com/CaioProiete/WP7MangoDevHub2011-DataAccess<br />
  49. 49. Performance e Boas Práticas<br />Nãoacumulemuitasalteraçõesemmemória<br />Grave as alteraçõesna BD (SubmitChanges) com frequênciaparaevitarperda de dados no término da aplicação<br />Utilize background threads<br />Operaçõesmaisdemoradasna BD nãodevembloquear a thread da interface com o utilizador<br />Optimize consultasread-only<br />Desligue o Object Trackingparaeconomizarmemória<br />Utilize índicesparapropriedadesmuitoutilizadasemconsultas<br />
  50. 50. Performance e Boas Práticas<br />Incluatabelas com dados jácarregados, se possível<br />Crie um projectoparacarregaros dados no emulador<br />Extraia o ficheiro .SDF com o Isolated Storage Explorer<br />Quandoutilizar bases de dados…<br />Prepare-se paraaumento no tempo de inicialização da aplicação e nautilização da memória<br />Use IsolatedStorageSettingsouficheiros simples paraconjuntos de dados empequenaquantidade<br />
  51. 51. Dados do Utilizador<br />
  52. 52. APIs Novas e Actualizadas no “Mango”<br />Chooser Tasksrelacionadas com dados do utilizador<br />EmailAddressChooserTask<br />PhoneNumberChooserTask<br />AddressChooserTask<br />Microsoft.Phone.UserDataparaacessodirecto<br />Contacts<br />Appointments<br />
  53. 53. AddressChooserTask<br />privateAddressChooserTaskaddressChooserTask;<br />// Constructor<br />publicMainPage()<br />{<br />this.addressChooserTask= newAddressChooserTask();<br />this.addressChooserTask.Completed+= addressChooserTask_Completed;<br />this.addressChooserTask.Show();<br />}<br />privatevoidaddressChooserTask_Completed(objectsender, AddressResulte)<br />{<br />if(null == e.Error && TaskResult.OK == e.TaskResult)<br /> {<br />... = e.DisplayName;<br />... = e.Address;<br />}<br />}<br />
  54. 54. Microsoft.Phone.UserData<br />Importante<br />As APIs de Contactos e Compromissossãoread-only<br />Não é possívelaceder dados de redessociaisquenãosão da Microsoft*<br />* Com excepção do Facebook<br />
  55. 55. Contactos / Compromissos<br />
  56. 56. Contactos: Olá, Mundo!<br />Contactscontacts = newContacts();<br />contacts.SearchCompleted+= newEventHandler<ContactsSearchEventArgs>((sender, e) =><br /> {<br />...= e.Results;<br /> });<br />// Ex: Obtertodososcontactos<br />contacts.SearchAsync(string.Empty, FilterKind.None, null);<br />
  57. 57. Contactos: Olá, Mundo!<br />Contactscontacts = newContacts();<br />contacts.SearchCompleted+= newEventHandler<ContactsSearchEventArgs>((sender, e) =><br /> {<br />...= e.Results;<br /> });<br />// Ex: Obtertodososcontactos<br />contacts.SearchAsync(string.Empty, FilterKind.None, null);<br />Informações de estado<br />expressão de filtro<br />(não é regex)<br />tipo de filtro: nome, email , telefoneoupinned to start)<br />
  58. 58. Contactos: Olá, Mundo!<br />Contactscontacts = newContacts();<br />contacts.SearchCompleted+= newEventHandler<ContactsSearchEventArgs>((sender, e) =><br /> {<br />...= e.Results;<br /> });<br />// Ex: Obtertodososcontactos<br />contacts.SearchAsync(string.Empty, FilterKind.None, null);<br />Informações de estado<br />// Ex: Procurarcontactos com "J" no nome<br />contacts.SearchAsync("J", FilterKind.DisplayName, null);<br />expressão de filtro<br />(não é regex)<br />tipo de filtro: nome, email , telefoneoupinned to start)<br />
  59. 59. Compromissos: Olá, Mundo!<br />Appointmentsappointments = newAppointments();<br />appointments.SearchCompleted+= newEventHandler<AppointmentsSearchEventArgs>((sender, e) =><br /> {<br />... = e.Results;<br /> });<br />// Ex: Obter o próximocompromisso (de agora até 1 semana)<br />appointments.SearchAsync(DateTime.Now,<br />DateTime.Now+ TimeSpan.FromDays(7),<br /> 1, null);<br />
  60. 60. Compromissos: Olá, Mundo!<br />Appointmentsappointments = newAppointments();<br />appointments.SearchCompleted+= newEventHandler<AppointmentsSearchEventArgs>((sender, e) =><br /> {<br />... = e.Results;<br /> });<br />// Ex: Obter o próximocompromisso (de agora até 1 semana)<br />appointments.SearchAsync(DateTime.Now,<br />DateTime.Now+ TimeSpan.FromDays(7),<br /> 1, null);<br />Data e hora de início<br />Data e hora de fim<br />Númeromáximo de registos<br />Informações de estado<br />
  61. 61. Demonstração<br />Base de Dados<br />AddressChooserTask<br />ConsultaaosContactos<br />ConsultaaosCompromissos<br />Código-fontedisponívelem:<br />https://github.com/CaioProiete/WP7MangoDevHub2011-DataAccess<br />
  62. 62. Performance e Boas Práticas<br />Sejaresponsável<br />A suapolítica de privacidadedeveindicarcomoutilizaoscontactos do utilizador<br />Prepare a aplicação<br />O tamanho da lista de contactosvariaparacadautilizador<br />A aplicaçãodeve saber lidar com atrasosnasconsultas<br />Eviteutilizar dados desactualizados<br />Dados retornadossãoumacópia<br />Repita a consultaquandoapropriado<br />
  63. 63. Questões?<br />
  64. 64. Obrigado!<br />Caio Proiete<br />caio@netponto.org<br />http://caioproiete.net<br />http://twitter.com/caioproiete<br />

×