Pointing datasource to correct folder - c#

I have built my application in c# and have an sql compact DB to go along with it. What do I need to change the location to in order for it to point to the same directory as the application.
For example:
Right now my DB is in C\Windows blah blah...
And in my code I make the source point to that...when I build the project my app is in bin\release along with my DB file, but in my code the source is not pointed to this DB file..does anyone know what I need to insert to point it to the correct DB file?
Thanks..

Is it always going to be in the same directory as the application executable? If so, perhaps you can just set the connection string using the path of the current assembly (assuming everything is in the same place):
string curPath = String.Format("{0}\\{1}", System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), "MyDatabase.sdf");
SqlCeConnection conn = new SqlCeConnection(String.Format("Data Source = {0}; Password ={1}", curPath , ":PASSWORD:");

Related

How to insert data into a local datatable in C#? [duplicate]

I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.

Updating my App.config Connection String from a text box

I want the user to be able to edit the connection string, I've set up a file browser dialogue where they can only select .accdb files, and I'm trying to have the save button overwrite the current connection string with the file path from the text box. I've had multiple errors at different times and I've ended up with a setup that seems tantalisingly close to working but I have a NullReferenceException error which says "Object reference is not set to an instance of an object". Hopefully this is a newbie mistake.
var configuration = ConfigurationManager.OpenExeConfiguration(#"\\Mac\Home\Documents\Visual Studio 2015\Projects\tiddlywinks\tiddlywinks\App.config");
var section = (ConnectionStringsSection)configuration.GetSection("connectionStrings");
section.ConnectionStrings["tiddlywinksDatabaseConnectionString1"].ConnectionString = #"Provider = Microsoft.ACE.OLEDB.12.0; Data Source ='" + filePathTextBox.Text + "'; Persist Security Info=False;";
configuration.Save();
This is the code that I have atm. Can anyone help?
Also, is there a way to achieve the same without having to tell the program where App.config is, surely Visual Studios knows where it's own config files are?
You can do that this way:
You go to your solution properties
Properties => Settings => Add new Settings
(Make sure Scope is "user")
and add a new sitting for your connection string, let's call it : ConnectionString
like mentioned in this post:
Applications sittings
then all you have to do is
Properties.Settings.Default.ConnectionString = TextBoxConnectionString.Text
Properties.Settings.Default.Save();
Give it a try, Hope it helps !
user cannot change application setting at run time.
It can be modified only at design time.
Use User settings for this.
How to : Using Application Settings and User Settings
Regards

Database connection from WPF

I have a folder 'Data' in my WPF application in which there is an .sdf database file.
This file is the database for my application.
When developing my app I used a fixed path to my db like this:
'Data Source=P:\Dropbox\Projects\MembersApp\MembersApp\bin\Debug\Data\RF_db.sdf'
Now I want to use the |DataDirectory| value so that the app always can find the db, were ever the app is installed. I found this solution on StackOverflow:
string executable = System.Reflection.Assembly.GetExecutingAssembly().Location;
string path = (System.IO.Path.GetDirectoryName(executable));
AppDomain.CurrentDomain.SetData("DataDirectory", path);
string dataSourceHome = "Data Source=|DataDirectory|\RF_db.sdf";
But is giving me an error on the last line 'Bad compile constant value'. I've tried with:
string dataSourceHome = #"Data Source=|DataDirectory|\RF_db.sdf";
But that doesn't work.
Any idea what's wrong here?
Do not change DataDirectory in your code; it is set by the installer and changing it will prevent your app from knowing where the data was installed. Just use:
string dataSourceHome = #"Data Source=|DataDirectory|\RF_db.sdf";
And nothing else. Do not call AppDomain.CurrentDomain.SetData("DataDirectory", path); that's what is breaking things.
You could use:
string dataSourceHome = string.Format("Data Source={0}\\RF_db.sdf", Environment.CurrentDirectory);
or
string dataSourceHome = string.Format("Data Source={0}\\RF_db.sdf", System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
It looks like your creating a ADO.Net connection string. Isn't there just information missing from your dataSourceHome?
Have a look at this post.
Or a different approach to creating the connection might be found on ConnectionStrings.com.

DataDirectory Set up project

I am doing a SETUP project for a C# winforms, sqlite application.
Connection string seems to a bit of a problem. The user will put the Database he wants to work with at a location(which v will tell him). In this example it is "C:\\Program Files(x86)\\DefaultCompany\\RSetup"; The user can work his own copy of the DB.
So I am setting the data directory to this path in the Program.cs Main
This is the only way I can think of. If there is a better way thats grt!!.
App.config
<add name="ConnString" connectionString="|DataDirectory|\MySQlite.db;Compress=True;Version=3"
providerName="System.Data.Sqlite" />
Program.cs
Setting the datadirectory to the path of the executable. Currently hard coded the path of the executable
static void Main()
{
AppDomain.CurrentDomain.SetData("DataDirectory","C:\\Program Files(x86)\\DefaultCompany\\RSetup");
This doesn't seem to be working. It doesn't give any error except the data is not blank. Doesn't seem to be working in both set up and the regular project
Thank you
JC
You could ask the user where the database is located, store that path somewhere (such as User Settings) and then you can retrieve it at any time. This would give the user more flexibility of where to put it and multiple users on the same machine could have their own database if desired.
Here is some pseudocode...
string dbLocation = Properties.Settings.Default.DatabaseLocation;
if (string.IsNullOrWhiteSpace(dbLocation)
{
dbLocation = AskUserForLocation();
Properties.Settings.Default.DatabaseLocation = dbLocation;
Properties.Settings.Default.Save();
}
AppDomain.CurrentDomain.SetData("DataDirectory",dbLocation);
Using this approach you could also add a menu option to allow the user to change the location if desired.
It also gives you the ability to retrieve the value anywhere, including where you create a connection, you can append the path to the location between where you read the connection string and you create a new connection.
SQLiteConnection myConnection = new SQLiteConnection;();
myConnection.ConnectionString = Path.Combine(Properties.Settings.Default.DatabaseLocation, myConnectionString);
myConnection.Open();

Unable retrieve records from SQLite database for smart device application

I am using SQLite.NET with C#[ visual studio 2008] and added the 'System.Data.SQLite.dll' as reference. The following code works with Windows Application for fetching data from my database file into a datagrid.
private void SetConnection()
{
sql_con = new SQLiteConnection("Data Source=emp.db;Version=3;");
}
public DataTable LoadData()
{
SetConnection();
sql_con.Open();
sql_cmd = sql_con.CreateCommand();
string CommandText = "select * from employeedetails";
transaction=sql_con.BeginTransaction();
DA = new SQLiteDataAdapter(CommandText, sql_con);
DS.Reset();
DA.Fill(DS);
DT = DS.Tables[0];
transaction.Commit();
sql_con.Close();
return DT;
}
Invoking in:
private void Form1_Load(object sender, EventArgs e)
{
EmpTable obj = new EmpTable();
this.dataGridView1.DataSource = obj.LoadData();
}
The same code not working with C# 'Smart Device Application'. It shows an exception: no such table 'employeedetails'.
For Smart Device Application I have added the System.Data.SQLite.dll from "SQLite/CompactFramework" folder.
Please help me to resolve this.
Thanks in advance.
I'm not sure if this is what is causing your issue, but we've had issues in the past with mobile devices and sqlite where this solved it:
For an application using the compact framework, you need to include SQLite.Interop.xxx.DLL in your project (in addition to the regular System.Data.SQLite.DLL). Make sure you set the file to copy if newer or copy always.
Keep in mind that you can't set a reference to the interop dll. You must include it in the project by adding it as a file.
For more information check this website under the Distributing The SQLite Engine and ADO.NET Assembly section.
Thank You Guys,
I've resolved the Problem. As 'siyw' said, the problem was the application could not find the "db file".
For windows application,
The db file has to be located in debug folder where the .exe file is generated. So that, no need to specify the path of the DB file.
For Smart Device Application,
The DB file will be generated in the root folder of the device. If we bind the db file with exe means, it wont find it and it will create a new database in root folder.
To avoid that, while crating CAB file we have to create custom folder [ ex. DBfolder ] and put the db file in the folder.
Set the path in the connection String as,
sql_con = new SQLiteConnection("Data Source=DBfolder/emp.db;Version=3;");
Now, the db is found by the Application.
sql_con = new SQLiteConnection("Data Source=emp.db;Version=3;");
I think you need to specify the full path here, and make sure it's correct. If the path is to a non-existent file, it will create a new emp.db database file there instead. This new file will obviously be empty and without any tables, hence it would give a no such table 'employeedetails' exception such as you're getting if you query it.

Categories