Usuário com melhor resposta
Problema acesso System.Assembly

Pergunta
-
Boa Tarde pessoal,
Estou com um problema de acesso.
Preciso obter o caminho da aplicação para informar o caminho correto do banco de dados sdf.
Código:
Dim Programa As System.Reflection.Assembly Dim strCaminho As String Programa = System.Reflection.Assembly.GetExecutingAssembly strCaminho = Programa.GetModules(0).FullyQualifiedName strCaminho = System.IO.Path.GetDirectoryName(strCaminho) & "\"
Quando a execução chega na linha "strCaminho = Programa.GetModules(0).FullyQualifiedName" recebo o erro:
Attempt to access the method failed: System.Reflection.Module.get_FullyQualifiedName()
Se isso não funcionar, como posso obter o caminho correto do banco de dados?
Obrigado
Analista Programador .Net www.fabner.com.br
segunda-feira, 30 de abril de 2012 16:58
Respostas
-
Fabner, falta-te a verificação se a base de dados não existir, então deve ser criada, usando os métodos DatabaseExists() e CreateDatabase() do datacontext respectivamente.
Pedro Lamas
DevScope | Senior Software Development Engineer & WP7 Development Speaker
www.pedrolamas.com | @pedrolamas- Marcado como Resposta FPimenta domingo, 6 de maio de 2012 15:12
terça-feira, 1 de maio de 2012 18:03 -
Fabner,
A primeira pergunta para saber qual a resposta correta é: essa sua base de dados será somente leitura, ou terá gravação nela?
Se for somente leitura, vc consegue acessar direto de uma pasta do seu projeto, mas a string de conexão não será a que está utilizando.
Agora, se for leitura e gravação, vc terá que copiar a base para o isolatedstorage, para despois acessá-la. Faço isso em alguns projetos e funciona perfeito.
Para copiar o arquivo e depois acessar, tente o seguinte:public void Teste() { using (WPDataContext db = new WPDataContext(WPDataContext.DBConnectionString)) { if (db.DatabaseExists() == false) { //Se quiser criar um banco vazio :) //db.CreateDatabase(); this.CopyDatabase(); } } } private void CopyDatabase() { using (Stream db = Application.GetResourceStream(new Uri("DBTeste.sdf", UriKind.Relative)).Stream) { using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream workDB = isoStore.CreateFile("DBTeste.sdf")) { using (BinaryWriter writer = new BinaryWriter(workDB)) { long length = db.Length; byte[] buffer = new byte[32]; int readCount = 0; using (BinaryReader reader = new BinaryReader(db)) { // read file in chunks in order to reduce memory consumption and increase performance while (readCount < length) { int actual = reader.Read(buffer, 0, buffer.Length); readCount += actual; writer.Write(buffer, 0, actual); } } } } } } }
Lembrando que o WPDataContext que está no exemplo, deve ser substituído pela sua classe de contexto.
[]s
Thiago J. Mônaco
MVP Windows Phone Development
MCP, MCAD, MCSD, MCDBA, MCTS, MCPD and MCT Professional
Scrum Developer I and Professional Scrum Master
http://www.windowsphonebrasil.net
@thiagojmonaco
- Marcado como Resposta FPimenta domingo, 6 de maio de 2012 15:11
quarta-feira, 2 de maio de 2012 14:10 -
Fabner,
A única coisa que acabei de perceber é que na sua string de conexão, falta um :
Public Const SQLConn As String = "Data Source=isostore:/DBTeste.sdf"
Veja o que acontece fazendo essa correção, pq de resto aparentemente está tudo certo.
Se não funcionar, me avise pois damos um jeito de resolver :)[]s
Thiago J. Mônaco
MVP Windows Phone Development
MCP, MCAD, MCSD, MCDBA, MCTS, MCPD and MCT Professional
Scrum Developer I and Professional Scrum Master
http://www.windowsphonebrasil.net
@thiagojmonaco
- Marcado como Resposta FPimenta domingo, 6 de maio de 2012 15:11
sexta-feira, 4 de maio de 2012 12:00
Todas as Respostas
-
Fabner, não precisas de fazer isso para a base de dados!
Aliás, todo o storage de uma app do Windows Phone é isolada (IsolatedStorage) e como tal, é relativa a esse mesmo storage (daí que nunca precisamos de saber o caminho da aplicação em si!)
A connection string deve ser algo tipo "Data Source=isostore:/A_minha_base_de_dados.sdf", bastando assim substituíres o nome da base de dados.
Vê aqui como deves fazer para indicar o caminho para a base de dados!
Pedro Lamas
DevScope | Senior Software Development Engineer & WP7 Development Speaker
www.pedrolamas.com | @pedrolamassegunda-feira, 30 de abril de 2012 17:42 -
Olá pedro.
Foi exatamente por ocorrer o problema com caminho da base de dados que tentei obter o caminho pelo assembly.
Minha string de conexao está exatamente igual a sua e mesmo assim gera o erro:
"The database file cannot be found. Check the path to the database. [ Data Source = \Applications\Data\7556F360-987A-4686-BEAB-76751ECA1E48\Data\IsolatedStore\DBTeste.sdf ]"
OBS: Estou programando em vb.net
Analista Programador .Net www.fabner.com.br
segunda-feira, 30 de abril de 2012 18:08 -
Fabner,
Se puder colocar o trecho do código que está utilizando, podemos dar uma olhada.
[]s
Thiago J. Mônaco
MVP Windows Phone Development
MCP, MCAD, MCSD, MCDBA, MCTS, MCPD and MCT Professional
Scrum Developer I and Professional Scrum Master
http://www.windowsphonebrasil.net
@thiagojmonaco
terça-feira, 1 de maio de 2012 15:36 -
Thiago,
Primeiro, gerei as classes responsáveis pela conexão de dados via SQLMETAL.
As classes estão no mesmo projeto. Depois comecei a criar um código para testar
Partial Public Class Consulta Inherits PhoneApplicationPage Public Const SQLConn As String = "Data Source=isostore:/DBTeste.sdf" Public Sub New() InitializeComponent() CarregaListaConsulta() End Sub Private Function ObterCaminho() As String Dim Programa As System.Reflection.Assembly Dim strCaminho As String Programa = System.Reflection.Assembly.GetExecutingAssembly strCaminho = Programa.GetModules(0).FullyQualifiedName strCaminho = System.IO.Path.GetDirectoryName(strCaminho) & "\" Return strCaminho End Function Private Sub CarregaListaConsulta() Dim objDA As clsAcessoDadosT = New clsAcessoDadosT(SQLConn) Dim qConsulta As IQueryable(Of Tb_Consulta) = Nothing qConsulta = objDA.Tb_Consulta Dim qConsulta2 As IQueryable(Of TbConsulta2) qConsulta2 = objDA.TbConsulta2 Dim qResultados = From oConsulta In qconsulta Join oConsulta2 In qConsulta2 On oConsulta.Id Equals oConsulta2.Id Select oconsulta.Id, oConsulta.Titulo Dim ListaItemsView As New List(Of clsListaItemsView) For i As Integer = 0 To qResultados.Count - 1 Dim oListaItemView As New clsListaItemsView With oListaItemView .Id = qResultados(i).Id .Titulo = qResultados(i).Titulo End With ListaItemsView.Add(oListaItemView) Next lstItens.ItemsSource = ListaItemsView End Sub End Class
Pode ver que o código é coisa simples, criei um sdf com duas tabelas com duas colunas cada, depois usei LINQ só para fazer o relacionamento e jogar em uma lista.
Abraço
Analista Programador .Net www.fabner.com.br
terça-feira, 1 de maio de 2012 17:57 -
Fabner, falta-te a verificação se a base de dados não existir, então deve ser criada, usando os métodos DatabaseExists() e CreateDatabase() do datacontext respectivamente.
Pedro Lamas
DevScope | Senior Software Development Engineer & WP7 Development Speaker
www.pedrolamas.com | @pedrolamas- Marcado como Resposta FPimenta domingo, 6 de maio de 2012 15:12
terça-feira, 1 de maio de 2012 18:03 -
Pedro,
Minha base existe em arquivo. ela está na mesma pasta do projeto.
No momento de rodar no Emulador o VS2010 tem que jogar o arquivo lá.
Pelo meno é o que eu entendi até agora.
Quando você cria uma base sdf e usa o sqlmetal, é necessário ainda criála em tempo de execução?
Analista Programador .Net www.fabner.com.br
terça-feira, 1 de maio de 2012 18:11 -
Não, se ela já existe está tudo ok, mas há uma alteração a fazer: em vez de "Data Source=isostore:/DBTeste.sdf" usas "Data Source=appdata:/DBTeste.sdf" pois a base de dados está na pasta da aplicação e não no IsolatedStorage!
Nota que tens de ter o ficheiro *.sdf no projecto e nas propriedades dele tem de ter o "Build Action" em "Content" para que ele copie a base de dados junto com a aplicação, e nota também que dado que ela vai estar no appdata, é só de read-only!
No artigo que te indiquei no meu primeiro post, isto é referido, e até a parte de como enviar uma base de dados pronta junto com a aplicação, copiar a mesma para o IsolatedStorage para que possa ser alterada, se assim for preciso!
Pedro Lamas
DevScope | Senior Software Development Engineer & WP7 Development Speaker
www.pedrolamas.com | @pedrolamasterça-feira, 1 de maio de 2012 18:15 -
Pedro,
Testei mas não deu certo.
Alterei isostore para appdata e o erro continua o mesmo.
Este erro está ocorrendo quando utilizo o ".Count" conforme codigo postado acima.
Analista Programador .Net www.fabner.com.br
terça-feira, 1 de maio de 2012 18:41 -
E o ficheiro da base de dados (*.sdf) está referenciado na raiz do projecto, e o seu "Build Action" em "Content"?
Faz também um Rebuild da aplicação e depois novo Deploy antes de experimentar novamente!
Pedro Lamas
DevScope | Senior Software Development Engineer & WP7 Development Speaker
www.pedrolamas.com | @pedrolamasterça-feira, 1 de maio de 2012 18:44 -
Mesmo assim o erro continua.
Fiz Rebuild e o BuildAction está como Content.
Analista Programador .Net www.fabner.com.br
terça-feira, 1 de maio de 2012 18:55 -
Fabner,
A primeira pergunta para saber qual a resposta correta é: essa sua base de dados será somente leitura, ou terá gravação nela?
Se for somente leitura, vc consegue acessar direto de uma pasta do seu projeto, mas a string de conexão não será a que está utilizando.
Agora, se for leitura e gravação, vc terá que copiar a base para o isolatedstorage, para despois acessá-la. Faço isso em alguns projetos e funciona perfeito.
Para copiar o arquivo e depois acessar, tente o seguinte:public void Teste() { using (WPDataContext db = new WPDataContext(WPDataContext.DBConnectionString)) { if (db.DatabaseExists() == false) { //Se quiser criar um banco vazio :) //db.CreateDatabase(); this.CopyDatabase(); } } } private void CopyDatabase() { using (Stream db = Application.GetResourceStream(new Uri("DBTeste.sdf", UriKind.Relative)).Stream) { using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream workDB = isoStore.CreateFile("DBTeste.sdf")) { using (BinaryWriter writer = new BinaryWriter(workDB)) { long length = db.Length; byte[] buffer = new byte[32]; int readCount = 0; using (BinaryReader reader = new BinaryReader(db)) { // read file in chunks in order to reduce memory consumption and increase performance while (readCount < length) { int actual = reader.Read(buffer, 0, buffer.Length); readCount += actual; writer.Write(buffer, 0, actual); } } } } } } }
Lembrando que o WPDataContext que está no exemplo, deve ser substituído pela sua classe de contexto.
[]s
Thiago J. Mônaco
MVP Windows Phone Development
MCP, MCAD, MCSD, MCDBA, MCTS, MCPD and MCT Professional
Scrum Developer I and Professional Scrum Master
http://www.windowsphonebrasil.net
@thiagojmonaco
- Marcado como Resposta FPimenta domingo, 6 de maio de 2012 15:11
quarta-feira, 2 de maio de 2012 14:10 -
Olá Thiago,
Respondendo a sua pergunta, sim, preciso armazenar, atualizar e deletar registros na base de dados.
Criei os metodos sugeridos em vb:
Public Class clsManutencao Public Sub VerificarBancoDeDados(ByVal StringConexao As String) Dim oContext As New clsAcessoDadosT(StringConexao) If Not oContext.DatabaseExists Then CopiarBancoDeDados() End If End Sub Private Sub CopiarBancoDeDados() Dim db As Stream = Application.GetResourceStream(New Uri("DBTeste.sdf", UriKind.Relative)).Stream Dim isoStore As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication() Dim workDB As IsolatedStorageFileStream = isoStore.CreateFile("DBTeste.sdf") Dim bWriter As BinaryWriter = New BinaryWriter(workDB) Dim Tamanho As Long = db.Length Dim Buffer(32) As Byte Dim intCont As Integer Dim bReader As BinaryReader = New BinaryReader(db) While intCont < Tamanho Dim intAtual = bReader.Read(Buffer, 0, Buffer.Length) intCont += intAtual bWriter.Write(Buffer, 0, intAtual) End While End Sub End Class
Depois, no código da MainPage
Partial Public Class MainPage Inherits PhoneApplicationPage Public Const SQLConn As String = "Data Source=isostore/DBTeste.sdf" ' Constructor Public Sub New() InitializeComponent() Dim oManutencao As New clsManutencao oManutencao.VerificarBancoDeDados(SQLConn) End Sub End Class
Até aqui sem problemas, o metodo é chamado mas quando executo o codigo já postado anteriormente, recebo o erro
Access to the database file is not allowed. [ 1981,File name = \Applications\Install\7556F360-987A-4686-BEAB-76751ECA1E48\Install\DBTeste.sdf,SeCreateFile ]
Tentei criar a base direto pela classe de contexto mas mesmo assim não funcionou:
Partial Public Class MainPage Inherits PhoneApplicationPage Public Const SQLConn As String = "Data Source=isostore/DBTeste.sdf" ' Constructor Public Sub New() InitializeComponent() Dim oContexto As New clsAcessoDadosT(SQLConn) If Not oContexto.DatabaseExists Then oContexto.CreateDatabase() Else Stop End If End Sub
Quando o metodo CreateDatabase é executado ocorre o seguinte erro:
Cannot create or delete database outside of application isolated storage.
Abraço
Analista Programador .Net www.fabner.com.br
sexta-feira, 4 de maio de 2012 00:51 -
Fabner,
A única coisa que acabei de perceber é que na sua string de conexão, falta um :
Public Const SQLConn As String = "Data Source=isostore:/DBTeste.sdf"
Veja o que acontece fazendo essa correção, pq de resto aparentemente está tudo certo.
Se não funcionar, me avise pois damos um jeito de resolver :)[]s
Thiago J. Mônaco
MVP Windows Phone Development
MCP, MCAD, MCSD, MCDBA, MCTS, MCPD and MCT Professional
Scrum Developer I and Professional Scrum Master
http://www.windowsphonebrasil.net
@thiagojmonaco
- Marcado como Resposta FPimenta domingo, 6 de maio de 2012 15:11
sexta-feira, 4 de maio de 2012 12:00 -
Fabner,
A única coisa que acabei de perceber é que na sua string de conexão, falta um :
Public Const SQLConn As String = "Data Source=isostore:/DBTeste.sdf"
Veja o que acontece fazendo essa correção, pq de resto aparentemente está tudo certo.
Se não funcionar, me avise pois damos um jeito de resolver :)[]s
Thiago J. Mônaco
MVP Windows Phone Development
MCP, MCAD, MCSD, MCDBA, MCTS, MCPD and MCT Professional
Scrum Developer I and Professional Scrum Master
http://www.windowsphonebrasil.net
@thiagojmonaco
Obrigado Thiago, era isso mesmo.
Resumindo, o VS2010 não copia a base automaticamente para o isostore (eu pensava que copiava).
A conexao ficou como "Data Source=isostore:/DBTeste.sdf"
Estava faltando o ":".
Utilizei o método de criação de base e agora não apresenta mais erro.
Agora vou fazer testes com inserção de dados.
Abraço
Analista Programador .Net www.fabner.com.br
domingo, 6 de maio de 2012 15:11