Unable to find table after successfully connecting to database file - c#

I'm currently a console application tool using C# where user is allowed to input the directory of the database file (which is located somewhere on the desktop), and I am required to get the .db file from the specified location and connect it followed by retrieving it's content from the table into a text file. However I'm getting a SQLite error stating that the table is not found. And whenever I run the code, It creates a copy of the .db file but its empty.
But this error doesn't show when I manually 'copy-paste' a copy of the .db file in my debug folder. So I'm wondering is it a must to keep a copy in the debug folder or is there any other way to allow something like a remote connection. (FYI. I'm really new to C# and SQLite).
connectionString = "DataSource=myDataBase.db";
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
connection.Open();
using (SQLiteCommand command = new SQLiteCommand("SELECT File,Path FROM Structure", connection))
{
using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
//Do some stuffs
}
reader.Close();
connection.Close();
}
}
}

Without a file path, the database file will be searched for in the current directory (whatever it happens to be).
When the database file does not exist, SQLite will happily create a new, empty one.
Include the complete directory in the connection string:
connectionString = "DataSource=C:\\some\\where\\myDataBase.db";

Related

Azure function read SQLite database

From a third party I am receiving a SQLite '.db3' database file. I wish to read the data stored within the database in an Azure function, but have no requirement to modify the database.
In my Azure function I have also uploaded a text file alongside the .db3 file, I can read the contents of this text file just fine, meaning that I have the URI and read privileges on the folder.
When I try to read some data from the database I get the error 'database is locked'.
Code to read the database is below. This works locally.
List<object> obs = new List<object>();
using(var con = new SQLiteConnection($"URI=file:{fullUri};mode=ReadOnly"))
{
con.Open();
using(var cmd = new SQLiteCommand(sql, con))
{
using(SQLiteDataReader rdr = cmd.ExecuteReader())
{
while(rdr.Read())
{
obs.Add(rdr.GetValues());
}
}
}
con.Close();
}
return obs;
How do I read the database?
I've had this problem before, reading a local file ... more than once. These are the steps I took depending on the scenario:
If your Azure Function is deployed using zipdeploy then under the "Configuration" > "Application Settings", change "WEBSITE_RUN_FROM_PACKAGE" from 1 to 0.
If the file you are trying to reference is saved under wwwroot on the Azure Function I would try put it somewhere else e.g. d:\local.

Storing Images in Project Folder - Directory Not Found Error Message

I am trying to save images to a SlideImages folder in my ASP.NET web forms website, using C#.
When I try to submit an image using the following code:
protected void btnSubmitImage_Click(object sender, EventArgs e)
{
//Get Filename from fileupload control
string filename = Path.GetFileName(fileuploadimages.PostedFile.FileName);
//Save images into SlideImages folder
fileuploadimages.SaveAs(Server.MapPath("SlideImages/" + filename));
//Open the database connection
con7.Open();
//Query to insert images name and Description into database
SqlCommand cmd = new SqlCommand("Insert into SlideShowTable(ImageName,Description) values(#ImageName,#Description)", con7);
//Passing parameters to query
cmd.Parameters.AddWithValue("#ImageName", filename);
cmd.Parameters.AddWithValue("#Description", txtDesc.Text);
cmd.ExecuteNonQuery();
//Close dbconnection
con7.Close();
txtDesc.Text = string.Empty;
BindDataList();
}
I get the below error message when trying to execute the 4th line of the code above.
An exception of type 'System.IO.DirectoryNotFoundException' occurred in mscorlib.dll but was not handled in user code. Additional information: Could not find a part of the path 'C:\Users\11342\OneDrive\Documents\4th Year\FYP\BallinoraWaterfallCommunity\SlideImages\'.
Here is my project folder structure. I am trying to store the images in the SlideImages folder of my project.
I managed to successfully store images in the 'Images' folder using the below code. I have tried to adapt it to fix the above problem, but I have not been able to.
protected void btnSubmit_Click(object sender, EventArgs e)
{
//Get Filename from fileupload control
string filename = Path.GetFileName(fileuploadimages.PostedFile.FileName);
//Save images into Images folder
fileuploadimages.SaveAs(Server.MapPath("Images/" + filename));
//Getting dbconnection from web.config connectionstring
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["BallinoraDBConnectionString1"].ToString());
//Open the database connection
con.Open();
//Query to insert images path and name into database
SqlCommand cmd = new SqlCommand("Insert into Group_Images(ImageName,ImagePath) values(#ImageName,#ImagePath)", con);
//Passing parameters to query
cmd.Parameters.AddWithValue("#ImageName", filename);
cmd.Parameters.AddWithValue("#ImagePath", "Images/" + filename);
cmd.ExecuteNonQuery();
//Close dbconnection
con.Close();
Response.Redirect("~/Admin.aspx");
}
You should use Server.MapPath("~/SlideImages). Notice the ~/ prefix which forces the mappath to start at the root of the web application.
Then add the file name as the file does not exist yet on disk but you should use System.IO.Path.Combine to combine the mapped root website path (and images folder) with the file name.
Also you should check if the directory exists or not. In your screen shot you have content in Images so this folder is probably being copied to your destination website path when you deploy. The other one is empty, it might not be created when you deploy your application because there is no content to copy.
Here is the modified code, check if it exists and create it if it does not. You should verify the web application's user context has sufficient privileges to create a directory in the root website directory.
var directory = Server.MapPath("~/SlideImages");
if(!System.IO.Directory.Exists(directory))
System.IO.Directory.Create(directory);
fileuploadimages.SaveAs(System.IO.Path.Combine(directory, filename));
Side note
You should wrap any instances that implement IDisposable with using blocks or make sure that they are disposed of in the dispose method of the containing type. I noticed in your 2nd example you created a SqlConnection instance and then called close later which is not good practice. Why that is is because if you have an Exception that occurs your SqlConnection, SqlCommand, or anything else that needs to clean up resources will stick around longer than needed which can cause issues later on like exceeding the max number of simultaneous allowed open connections to a Sql Server or not being able to serve an image because there is a lock on the file.

I cant open sqlite database

I am required to get sqlitedb in located here
C:\Users\xxx\AppData\Local\Mozilla\Firefox\Profiles\zxl8ocql.default.places.sqlite.
The following code works while accessing Google Chrome data:
private const string PathToChromeData = #"\Google\Chrome\User Data\Default\History";
private const string PathToFirefoxData = #"\Mozilla\Firefox\Profiles\zxl8ocql.default\places.sqlite";
string pathh = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), PathToFirefoxData);
using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + pathh + ";Version=3;New=False;;"))
{
connection.Open();
SQLiteDataAdapter adapter = new SQLiteDataAdapter("Select * from moz_places", connection);
DataSet ds = new DataSet();
adapter.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
So I slightly changed it for getting Firefox data. However I am getting this exception:
unable to open database file
Then I have checked few similar threads on SO. And realized that Firefox locks this database while its running. And I closed the Firefox even changed the location of database. I checked the connection string, but it seems correct. What is wrong here?
You got a size of 0 KB, because you are searching the history file in the wrong directory.
Replace Local with Roaming and you will get the original places.sqlite file.
The new path would be
C:\Users\xxx\AppData\Roaming\Mozilla\Firefox\Profiles\zxl8ocql.default\places.sqli‌​te.
Why you found a db of 0 KB in Local?
When you try to open a db file with API, if file does not exist it will create a new empty file. That is why you found a 0 KB sqlite file in local.
Well I am also getting the same issue as described above.
I am looking in to it. I will post a solution if I got.
I am glad that I figured it out and fixed it.
The problem was with the sql version; db was created with a higher version and I was trying to open it with a lower version of sqlite.
It should be handled and at least they should display a proper message.
To open firefox db you require sqlite version 3.8.x.

ASP.NET C# file locked on folder by process not allowing new OleDbConnection connections to different files

I am trying to solve an issue that i have been smashing my head against the wall about. What i am trying to accomplish is to read the table names (sheet names) from an excel file that is stored in a folder on the web server. I am going to use these sheet names to determine what sheet i will read values from. The problem that i am having is that users randomly come across the issue where a file gets locked by the asp.net process and then no other users in different sessions and with different files can access their files on the folder. Once the file is locked i am unable to delete the file from the data folder because it is being used by another process.
The only thing that will free up the folder is to do an app pool refresh. I am running my app pool in X64 to accomondate for the XLSX and XLS files. I have had the server team run the procmon tool to see what processes have the folder locked up and got no useful information.
I have my connection to my file location wrapped in using statements to make sure proper disposal is being done. When a file gets locked or doesn't exit the process of the using statement it does not allow for users to create a new connection to another completely unique and different file in the same location. Users are able to write a file to the folder location and delete a file but not able to execute the conn.Open in the below code. Users are not able to navigate to the folder location and delete the file that is locked by the process either. As i said earlier this happens randomly and is hard to recreate. I have looked into whether the folder had indexing or backup jobs running but they do not.
I have tried to put a lock object around the processing so that no other process can access the file while i am pulling values from the file. The tricky part is that after an app pool refresh i cannot get the file lock to occur for a while....its like it runs out of connection objects and or the app pool bogs down to where 2 processes try and access the file simultaneously or something. Our app pool refreshes every 24 hours so it will automatically release the object and we are able to to delete the file and also able to pull data from other excel sheet on the folder. But we can't run an app pool refresh randomly during the day if we see this locked process issue.
public const string ExcelConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1;ApplicationIntent=ReadOnly;ReadOnly=True;\"";
DataTable dt = ExecuteDataTable(connectionString, String.Format("SELECT * FROM [{0}] ", sheetName.Trim()));
string connectionString = DataServices.ExcelConnection;
string fileConnection = string.Format(connectionString, mappedPath.Trim());
Object lockObject = new Object();
lock (lockObject)
{
// Setup the connection to the file
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(fileConnection))
{
if (File.Exists(mappedPath))
{
try
{
conn.Open();
this.sheetNamesFromFile = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
if (this.sheetNamesFromFile.Rows.Count > 0)
{
this.sheetName = RetrieveSheetName(this.sheetNamesFromFile, fileName);
ViewState.Add("SheetName", this.sheetName.ToString().Trim());
if (!string.IsNullOrEmpty(this.sheetName))
{
this.massUploadExcelData = DataServices.GetExcelData(conn.ConnectionString, this.sheetName, fileName); // getexcledata has the following code to grab all data from the sheet name - DataTable dt = ExecuteDataTable(connectionString, String.Format("SELECT * FROM [{0}] ", sheetName.Trim()));
if (this.massUploadExcelData.Rows.Count < 1)
{
this.ShowMessageOnSubmit(this.Labels.GetLabel("norecordsintable"), false);
}
}
else
{
this.ShowMessageOnSubmit(this.Labels.GetLabel("uploadnosheet"), false);
}
}
}
catch (System.Data.OleDb.OleDbException dataExp)
{
EventLogging.LogError("An error has occurred when saving a mass upload file, the file the user is using could have corrupt data : Mapped path = " + mappedPath + " File Path and Name = " + fileName, dataExp);
this.error = "An error has occured when trying to load a mass upload file, user might have corrupt data. exception = " + dataExp;
return string.Empty;
}
}
else
{
EventLogging.LogError("The file does not exist that is trying to be accessed in the application, mapped path - " + mappedPath);
}
}
// Delete the file in data folder, since we already have the datatable of the data and sheet name
if (File.Exists(mappedPath))
{
DeleteFile(mappedPath);
}
}
Any thoughts and direction would be appreciatted.

How to create a connection string outside web.config

Just thinking about this, is it possible to create a connection string outside the ASP.NET's web.config?
Possibly you're looking for configSource?
Yes you can store it anywhere it is just text.... The web.config is just a XML document that stores configuration settings about your application. You could just as easily create another XML file or a text file and read it in from there. You just wouldnt be able to use:
ConfigurationManager.ConnectionStrings[].ConnectionString
You can create a connection string through the usage of .udl file.
UDL File Creation :
Right-click on the desktop, or in the folder where you want to create the file.
Select New, then Text Document.
Give the Text Document any name with a .udl extension ("Show file extensions" must be enabled in folder options).
A window will pop up warning that "If you change a filename extension, the file may become unusable. Are you sure you want to change it?" Select Yes.
You have now successfully created a UDL file.
Now you need to implement the settings inside the .udl file according to your requirements. A video tutorial has been provided to explain you the whole procedure of using .udl file to create a connection string for MS SQL Server.
http://visiontechno.net/studymats/udlcreation.html
You can have it in another .config file that gets pulled in by your web.config like this:
<appSettings file="../Support/config/WebEnvironment.config">
</appSettings>
You can then use it in your code like this:
System.Configuration.ConfigurationManager.AppSettings["DefaultConnection"]
We have it such that this file isn't physically under our site, but it is virtually under it. That is the "Support" directory above is a virtual directory. Details can be found HERE.
You can use following in case of MSSQL server
string connectionString = "Your Connection string"
using (SqlConnection con = new SqlConnection(connectionString))
{
//
// Open the SqlConnection.
//
con.Open();
//
// The following code uses an SqlCommand based on the SqlConnection.
//
using (SqlCommand command = new SqlCommand("SELECT TOP 2 * FROM Dogs1", con))
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("{0} {1} {2}",
reader.GetInt32(0), reader.GetString(1), reader.GetString(2));
}
}
}

Categories