WP8, VS12, & C#
I've started creating an app which allows me to store relational data in a local database using LINQ to SQL.
What I'd like to do next is be able to update the existing data...I would click an icon in the appbar and be taken to the previously saved data so I could update it.
I've looked on msdn... Local database for Windows Phone, and I would like to know if the following code I see at section Using the database > Updating data is valid given my LINQ to SQL set-up. If so, how do I go about adding this code to allow updating?
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
//Call base method
base.OnNavigatedFrom(e);
//Save changes to the database
toDoDB.SubmitChanges();
}
If anyone could point to a working example or help me hook up the ability to update data, I would be grateful.
Much Thanks,
k
Yhello, dunno if you still working on your project but I've got a solution for you.
From your site (msdn), here what I found :
First, query the database for the object that is to be updated. Then, modify the object as desired. Finally, call the SubmitChanges method to save the changes to the local database.
So, you need to query your db (example from my own VB.net code)
Dim monContact = From contact As Authentification In bddGLI.TableAuth Select contact
Execute the query and get the result in a collection
Dim resultCollection = New ObservableCollection(Of Authentification)(monContact)
Run through this collection with a ForEach loop and modify your object
For Each elem As Authentification In resultCollection
elem.Mail = txtEmail.Text
elem.Nom = txtNom.Text
elem.Prenom = txtPrenom.Text
Next
And don't forget to save your db
bddGLI.SubmitChanges()
Now, how to check if you really updated your data ?
Where I create my db, i inserted some data test in my table
Using db As New GeoLiveInfoDataContext(GeoLiveInfoDataContext.DBConnectionString)
If db.DatabaseExists() = False Then
db.CreateDatabase()
Dim contact As New Authentification
With contact
.Nom = ""
.Prenom = ""
.Mail = ""
End With
db.TableAuth.InsertOnSubmit(contact)
db.SubmitChanges()
End If
End Using
http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh286408(v=vs.105).aspx
Go to C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\IsolatedStorageExplorerTool
SHIFT + right clic => open prompt here
ISETool.exe ts xd {ID APP HERE FROM MANIFEST } {PATH}
Don't forget to install your app on the emulator or device (not debugging)
Now at your path, you have a .sdf which can be open with SQL server Compact Edition.
Do this command before and after updating and check the difference.
Use Sqlight -- Here is a great example http://code.msdn.microsoft.com/wpapps/Using-Sqlite-with-WP8-52c3c671
The important thing in updating the data in the database is, that you handle with the same object which results the query from database and don't copy it. You can pass the object from the query results to other objects or functions but make sure that it is still the same object on the heap. Just in this case the SubmitChanges works. I did it the first time wrong and copied it for the page object and then passed it back and the SubmitChanges didn't work.
Related
I am developing a VB.NET update system for a volunteer organisation’s MS Access database. The database is protected by a password as it contains personal information. I have created the application using the VB designer. I need to be able to code the application so that, if the owner decides to change the MS Access password, they will have no need to come back to me to change the code and rebuild the solution. In other words, I do not want the password to be hard coded in the app.config file or the settings.designer.vb file. My code should not need to know the password as a simple call to one of the Fill functions can test any password entered by the user. My problem is that I have found no way to alter the connection string that is tested in the setttings.designer.vb code whenever the database is accessed. I am using Visual Studio 2017.
I have spent a long time searching the web for answers and have tried various solutions involving the configurationmanager without success. I am new to this area so I would be most grateful if anyone here can help.
Here is my latest attempt which still produces an invalid password error even though the third debug statement suggests that the connection string, including the password, has been correctly set.
Public Sub UpdateConnString(connString As String)
Dim configFileMap As New ExeConfigurationFileMap()
Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(configFileMap.ExeConfigFilename)
Dim connStringName As String = "TestConnectionString"
Debug.Print("0 " + config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString)
config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString = connString
Debug.Print("1 " + config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString)
config.Save(ConfigurationSaveMode.Modified, True)
Debug.Print("2 " + config.ConnectionStrings.ConnectionStrings(connStringName).ConnectionString)
End Sub
Just because a connection string is stored in the config file, you aren't required to use it as it is. You can read in that default value and then edit it before using it, e.g.
Dim builder As New OleDbConnectionStringBuilder(My.Settings.DefaultConnectionString)
builder.DataSource = dataSource
Dim connectionString = builder.ConnectionString
You can add or modify any part of a connection string you want that way at run time.
Thank you for your response. Unfortunately, the code throws a compilation error - "DefaultConnectionString is not a member of My.Settings".
Fortunatley I have now managed to find a working solution:
'My.Settings.Item("TestConnectionString") = connectionString
I have included database in my project(at root).
The connection string
Data Source=|DataDirectory|\TSM_DB.sdf;Password=xxx;Persist Security Info=True;Max Database Size=512
TSM_DB.sdf properties:
Build Action = Content
Copy to Output Directory = Copy if newer
Dataset properties:
Build Action = None
Copy to Output Directory = Do Not Copy
My problem:
When I try to insert data into the database it gets inserted to the database present in Debug folder and not in the database which is included in the project...
And that’s why (obviously) my select statement does not find any record in the database (according to my connection string)...
I think the query (code) is perfectly fine, but some sort of settings need be done.
How do I solve this issue?
EDIT :
Example Select Code (working : when connection string path is Absolute)
Try
Dim cnt_temp
Dim SQLquery As String
Dim myConString As String = My.Settings.TSM_DBConnectionString
con.ConnectionString = myConString
SQLquery = "SELECT * FROM tbl_outward"
Dim DA As SqlCeDataAdapter, Ds As New DataSet, Dtb As New System.Data.DataTable
DA = New SqlCeDataAdapter(SQLquery, con)
DA.Fill(Ds)
Dtb = Ds.Tables(0)
cnt_temp = Dtb.Rows.Count
MsgBox(cnt_temp)
con.Close()
Catch ex As Exception
MsgBox("Error..!", MsgBoxStyle.Exclamation)
End Try
When I try to insert data into the database it gets inserted to the database present in Debug folder and not in the database which is included in the project...
Which is exactly what you told it to do, and is what you want. The database in your project folder is part of the source code. When you test or debug your code, the data changed is part of your test or temporary debug output, not your source code.
When you test your code, would you want the test overwriting your source code? I hope not, that would destroy your source; and when you deploy your project you don't usually deploy your source code. The same is true of your data; the data in your project is part of your application and is not the end-user data. When you install your application your source data gets installed to DataDirectory, which is part of your application and is not user data; the user may not even be able to write to it.
When you uninstall or update your application, DataDirectory gets uninstalled or updated. You don't want to do that to your user's data; would you like it if every time you updated Microsoft Word it deleted every Word file on your drive? That's what would happen if Word stored user data in its equivalent of DataDirectory.
DataDirectory is only for your app's private use. If a user needs this data you should copy it to a user-writable place that won't get deleted, like Environment.SpecialFolder.ApplicationData.
Further explanations at this answer.
I have been searching the web looking for a way to open a WORD file from a secure network folder by impersonating a user who has access. The closest I've come to finding the answer was this from 2 years ago:
Impersonating in .net (C#) & opening a file via Process.start
Here is the code that I am using. When I set the arguments = LocalFile_Test, everything works perfectly because the user is accessing the local c:\ that is has access to. But when I set arguments = RemoteFile_Test, Word opens up a blank document which is the same effect as if I put garbage in the arguments. So it appears that it cannot find the file even though when I login with the user/domain/password that I specify in the properties below, I can find that exact file name and it is not empty. Does anything jump out at you right away? I appreciate your time.
Dim LocalFile_Test As String = "C:\New.docx"
Dim RemoteFile_Test As String = "\\Server1\Apps\File\New.docx"
Dim MyStartInfo As New System.Diagnostics.ProcessStartInfo
MyStartInfo.FileName = "C:\Program Files\Microsoft Office\Office12\WINWORD.exe "
MyStartInfo.Arguments = LocalFile_Test
MyStartInfo.LoadUserProfile = True
MyStartInfo.UseShellExecute = False
MyStartInfo.UserName = "specialuser"
MyStartInfo.Domain = "mydomainname"
MyStartInfo.Password = New System.Security.SecureString()
MyStartInfo.Password.AppendChar("p"c)
MyStartInfo.Password.AppendChar("a"c)
MyStartInfo.Password.AppendChar("s"c)
MyStartInfo.Password.AppendChar("s"c)
Process.Start(MyStartInfo)
My understanding is that you are trying to get a password protected file from a server, and when you do process start, it just opens up a blank word doc. I think the error is how you are trying to get the file, I think you have to map the actual physical path of the file on the server, like
System.Web.HttpContext.Current.Server.MapPath("\\Server1\Apps\File\New.docx")
From there, I am fairly certain, you need to create network credentials for the user like
System.Net.NetworkCredential=New NetworkCredential(userName:=, password:=)
Finally, once that is done, you can either write the file, or transmit the file like so...
System.Web.HttpContext.Current.Response.TransmitFile(file name)
System.Web.HttpContext.Current.Response.WriteFile(file name)
Then,once you get the file, you can try to open it with process start.
Hope that helps, let me know if what I said doesn't work.
I have this old Access database (2000 format) which i want to convert to the new .accdb 2007 format. I know just basic stuff about Access so I knew it was a bit of a challenge, I decided to do it anyway.
It has two files, one appears to have all the tables "WOSS_Tables.mdb" (duh), the other ("WOSS.mdb") has a bunch of Forms and a Module and lots of code when I go to Database Tools / Visual Basic.
I opened them both in Access 2010 and did a "Save and Publish", "Save ass .accdb" and everything went fine with that.
So the first thing that pops up when I open the WOSS.mdb is a Login Form, but when i try to log in it says:
So i get it, it does not find the new file.
Digging into the WOSS.mdb file (Now WOSS.accdb) i find a Module which has sort of a connectionString named ruta (route in spanish), so i changed it, pointing it to my desktop for now:
Option Compare Database
Option Explicit
Public xdescripcion As String
'** Ruta para abrir la base de datos
'Public Const Ruta = "\\the_super_secret_old_route\"
Public Const Ruta = "C:\Users\AlexXPS\Desktop\Woss"
Public M
And found on a bunch of Forms, lines like these:
Set dbs = DBEngine.Workspaces(0).OpenDatabase(Ruta + "WOSS_Tables.mdb", False, False, "")
Set dbs = OpenDatabase(Ruta + "WOSS_Tables.mdb", False, False, "")
Updated those with "WOSS_Tables.accdb" aswell.
Now, I click Save, then Debug menu, Compile then i close and reopen and i still get the same error as above, like it didnt compile at all?
If i check the Forms and the Module code, its like i changed it Ruta is correctly pointing at my desktop and the other changes were saved correctly aswell.
So, what am i doing wrong?
PS: Sorry for the long post :(
EDIT!!!!!!!
Okay, messing around with the code i found something out:
On the Logon screen theres a ComboBox which is supposed to show all the UserNames in the Users table, the ComboBox has a simple query on its "Row Source" Data Property
SELECT DISTINCTROW [Usuarios].[Name], [Usuarios].[Name] FROM Usuarios ORDER BY [Usuarios].[Name];
Which has nothing to do with the "Ruta" variable I changed!
So now the question is, how can I tell that ComboBox that the location of its source db changed? (Its not "\the_super_secret_old_route\WOSS_Tables.mdf" anymore, its "C:\Users\AlexXPS\Desktop\Woss/WOSS_Tables.accdb")
The previous error message was shown because of the ComboBox not finding the database :), not the other code (Which of course also needed to be changed)
I hope im explaining myself well, if not, heres a screenshot!
Look again at the change you made to the Ruta constant.
'Public Const Ruta = "\\the_super_secret_old_route\"
Public Const Ruta = "C:\Users\AlexXPS\Desktop\Woss"
Notice the previous version ended with a backslash; the new version doesn't. So in your OpenDatabase() statements, you're giving the full path to the database like this ...
"C:\Users\AlexXPS\Desktop\WossWOSS_Tables.mdb"
or maybe it's like this with your other changes ...
"C:\Users\AlexXPS\Desktop\WossWOSS_Tables.accdb"
Either way, it seems you're missing a backslash before the file name.
Edit: Your updated question indicates you have this as the row source for a combo box:
SELECT DISTINCTROW [Usuarios].[Name], [Usuarios].[Name]
FROM Usuarios ORDER BY [Usuarios].[Name];
Open the navigation pane, right-click its header, then choose Navigation Options ... Place a check mark in the box next to Show Hidden Objects. Then verify there is a linked table named Usuarios. You'll need to update the location of the db which contains the actual Usuarios source table. Do that by selecting the Database Tools section of the ribbon, then choose Linked Table Manager to update the link's location.
Edit2: You can examine the .Connect property of the Usuarios link to determine the location of the db file which contains the source table.
Public Function BackEndLocation() As String
BackEndLocation = Split(CurrentDb.TableDefs("Usuarios").Connect, "=")(1)
End Function
That way you might be able to get rid of the Ruta constant and avoid the need to update that constant and the name of the database file everywhere your code calls OpenDatabase(). Just use the Linked Table Manager to update the links when the file name or location changes, then rely on the BackEndLocation() function to tell your code where it its.
I have the following code:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.Run "Routine"
obj.CloseCurrentDatabase
Set obj = Nothing
The problem I'm experimenting is a pop-up that tells me Access can't set the focus on the other database. As you can see from the code, I want to run a Subroutine in another mdb. Any other way to achieve this will be appreciated.
I'm working with MS Access 2003.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user.
This is an intermittent error. As this is production code that will be run only once a month, it's extremely difficult to reproduce, and I can't give you the exact text and number at this time. It is the second month this happened.
I suspect this may occur when someone is working with this or the other database.
The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database.
Maybe, it's because of the first line in the 'Routines' code:
If vbNo = MsgBox("Do you want to update?", vbYesNo, "Update") Then
Exit Function
End If
I'll make another subroutine without the MsgBox.
I've tried this in our development database and it works. This doesn't mean anything as the other code also workes fine in development.
I guess this error message is linked to the state of one of your databases. You are using here Jet connections and Access objects, and you might not be able, for multiple reasons (multi-user environment, unability to delete LDB Lock file, etc), to properly close your active database and open another one. So, according to me, the solution is to forget the Jet engine and to use another connexion to update the data in the "other" database.
When you say "The dataflow is to update all 'projects' once a month in one database and then make this information available in the other database", I assume that the role of your "Routine" is to update some data, either via SQL instructions or equivalent recordset updates.
Why don't you try to make the corresponding updates by opening a connexion to your other database and (1) send the corresponding SQL instructions or (2) opening recordset and making requested updates?
One idea would be for example:
Dim cn as ADODB.connexion,
qr as string,
rs as ADODB.recordset
'qr can be "Update Table_Blablabla Set ... Where ...
'rs can be "SELECT * From Table_Blablabla INNER JOIN Table_Blobloblo
set cn = New ADODB.connexion
cn.open
You can here send any SQL instruction (with command object and execute method)
or open and update any recordset linked to your other database, then
cn.close
This can also be done via an ODBC connexion (and DAO.recordsets), so you can choose your favorite objects.
If you would like another means of running the function, try the following:
Dim obj As New Access.Application
obj.OpenCurrentDatabase (CurrentProject.Path & "\Working.mdb")
obj.DoCmd.RunMacro "MyMacro"
obj.CloseCurrentDatabase
Set obj = Nothing
Where 'MyMacro' has an action of 'RunCode' with the Function name you would prefer to execute in Working.mdb
I've been able to reproduce the error in 'development'.
"This action cannot be completed because the other application is busy. Choose 'Switch To' to activate ...."
I really can't see the rest of the message, as it is blinking very fast. I guess this error is due to 'switching' between the two databases. I hope that, by educating the user, this will stop.
Philippe, your answer is, of course, correct. I'd have chosen that path if I hadn't developed the 'routine' beforehand.
"I've been able to reproduce this behaviour. It happens when the focus has to shift to the called database, but the user sets the focus ([ALT]+[TAB]) on the first database. The 'solution' was to educate the user." As it is impossible to prevent the user to switch application in Windows, I'd like to close the subject.