How to specify a relative SQLite database path in C#? - c#

My database is located outside the application folder
Example:
Database: SampleApplication\Database\Database.sqlite
Application: SampleApplication\Application\program.cs
My code is as below.
string relativePath = #"SampleApplication\Database\Database.sqlite";
string currentPath;
string absolutePath;
string connectionString;
currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
absolutePath = Path.Combine(currentPath, relativePath);
connectionString = string.Format("Data Source={0};Version=3;Pooling=True;Max Pool Size=100;", absolutePath);
m_dbConnection = new SQLiteConnection(connectionString);
m_dbConnection.Open();

Alright, I figured it out guys.
string relativePath = #"Database\Database.sqlite";
var parentdir = Path.GetDirectoryName(Application.StartupPath);
string myString = parentdir.Remove(parentdir.Length -34, 34);
string absolutePath = Path.Combine(myString, relativePath);
string connectionString = string.Format("Data Source={0};Version=3;Pooling=True;Max Pool Size=100;", absolutePath);
m_dbConnection = new SQLiteConnection(connectionString);
m_dbConnection.Open();
I removed the characters from the parentdir till SampleApplication\ and added it with the relativePath. That makes an absolutePath to the database.
The number 34 in the third line signifies how many characters to be remove from the end of parentdir.

try this
var parentdir =Path.GetDirectoryName(System.Windows.Forms.Application.StartupPath);

I guess you need to modify your connection string, so for basic connect to SQL LITE DATABASE, you would do this:
Data Source=c:\mydb.db;Version=3;
enter code here
In memory database:
Data Source=:memory:;Version=3;New=True;
With password
Data Source=c:\mydb.db;Version=3;Password=myPassword;
You could do this also in your c# code:
var connectionString = #"data source=c:\TestData\testsqldata.s3db; Version=3;"
connection = new SQLiteConnection(connectionString);
connection.Open();

In an ASP CORE project if your db is in Data folder, write the following code in startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyContext>(options =>
options.UseSqlite("Data Source=" +
Path.Combine(Directory.GetCurrentDirectory(), "Data\\sqlite.db"))
);
}

Related

Run a sql script in c# (.asp net)

I just want the directory to open to "project_name\Scripts(sub_folder)\merge.sql"
I can't get rid of 'C:' and I cant get the actually data file to appear.
I received an"System.io.directorynotfoundexcpetion".
Here's my code:
private void MergeQuery()
{
//might need to change C: drive directory
//string derefQuery = #"\.\mergeSQL.sql";
using (SqlConnection mer = new SqlConnection(#"Data Source = address_name; Initial Catalog = catalog_name; Integrated Security=SSPI"))
{
{
mer.Open();
string path = Path.GetDirectoryName("\\project_name\\Scripts\\mergeSQL.sql ");
string mergeScript = System.IO.File.ReadAllText(path);
System.Collections.Generic.IEnumerable<string> commandStrings = Regex.Split(mergeScript, #"^\s*GO\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase);
foreach (string commandString in commandStrings)
{
if (commandString.Trim() != "")
{
using (var command = new SqlCommand(commandString, mer))
{
command.ExecuteNonQuery();
}
Label2.Text = "Query merged";
}
}
}
}
first, there is an error in line
string path = Path.GetDirectoryName("\\project_name\\Scripts\\mergeSQL.sql ");
In that line you're getting directory path from file path, so path variable becomes \\project_name\\Scripts\\ or something similar. On next line you're trying to read file from that path variable, not from file.
What you need is to get path relative to web site root and then read file, like this
string path = HostingEnvironment.MapPath("~/Scripts/mergeSQL.sql ");
string mergeScript = System.IO.File.ReadAllText(path);
this way asp.net will get correct path from your website root's subfolder.

Error restoring SQL Server backup to a new database

I created a backup of a SQL Server database named mydb. I need to restore it programmatically with a C# code.
The restore must create a new database named mydbnew. I'm doing it using the Microsoft.SqlServer.Management.Smo library.
The code is this:
public void RestoreDatabase()
{
string databaseName = "mydbnew";
string userName = "user";
string password = "password";
string serverName = "(local)\\SQLEXPRESS";
string sourcePath = #"c:\temp\";
string fileName = $"mydbbackup.bak";
ServerConnection connection = new(serverName, userName, password);
Server sqlServer = new Server(connection);
BackupDeviceItem deviceItem = new(sourcePath + fileName, DeviceType.File);
Restore restore = new Restore();
restore.Database = databaseName;
restore.ReplaceDatabase = true;
restore.NoRecovery = false;
restore.Devices.Add(deviceItem);
RelocateFile dataFile = new RelocateFile();
dataFile.LogicalFileName = databaseName + "_data";
dataFile.PhysicalFileName = databaseName + ".mdf";
RelocateFile logFile = new RelocateFile();
logFile.LogicalFileName = databaseName + "_log";
logFile.PhysicalFileName = databaseName + ".ldf";
restore.RelocateFiles.Add(dataFile);
restore.RelocateFiles.Add(logFile);
restore.SqlRestore(sqlServer);
restore.Devices.Remove(deviceItem);
}
I get an error at restore.SqlRestore(sqlServer):
Logical file 'mydbnew_log' is not part of database 'mydbnew'. Use RESTORE FILELISTONLY to list the logical file names.
RESTORE DATABASE is terminating abnormally.
What is wrong in my code?
Looks to be 2 issues, first one:
RelocateFile logFile = new RelocateFile();
dataFile.LogicalFileName = databaseName + "_log";
dataFile.PhysicalFileName = databaseName + ".ldf";
You are creating a object with name logFile, but in the next statement setting values for the old variable.
I expect you want it to be:
RelocateFile logFile = new RelocateFile();
logFile.LogicalFileName = databaseName + "_log";
logFile.PhysicalFileName = databaseName + ".ldf";
The next issue, the LogicalFileName is the actual logical name in the original database. But, the PhysicalFileName is the new name.
So, as example, if your DB is like this,
,
then the code is like this:
RelocateFile dataFile = new RelocateFile();
dataFile.LogicalFileName = "Mine";
dataFile.PhysicalFileName = sourcePath + databaseName + ".mdf";
RelocateFile logFile = new RelocateFile();
logFile.LogicalFileName = "Mine_log";
logFile.PhysicalFileName = sourcePath + databaseName + ".ldf";
The RelocateFile uses the logical name of old (original database), but creates file in the new location mentioned in your PhysicalFileName
The above code creates file with new name.
Good luck.
Solved.
I changed the Relocate section with this version:
RelocateFile dataFile = new RelocateFile();
dataFile.LogicalFileName = "mydb";
dataFile.PhysicalFileName = Path.Combine(#"C:\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\MSSQL\DATA", "mydbnew.mdf");
RelocateFile logFile = new RelocateFile();
logFile.LogicalFileName = "mydb_log";
logFile.PhysicalFileName = Path.Combine(#"C:\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\MSSQL\DATA", "mydbnew.ldf");
Of course I must work to get the paths and names dynamically, but it works.

How to open multiple Microsoft Access (mdb) files in C#?

Referring to this question, I figured out how open and connect to a single mdb file.
At the moment I am doing:
String accessConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=C:\MyMDB\MyMDBFile.mdb;
Persist Security Info = False; ";
using (OleDbConnection accessConnection = new OleDbConnection(accessConnectionString))
{
ReadContent();
}
But I want to open multiple files from the directory, basically I want to:
String[] mdbFiles = Directory.GetFiles(#"C:\MyMDB\", "*.mdb");
And use this in the accessConnectionString
I know it should be something like,
foreach (var filePath in mdbFiles)
{
accessConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;"
+ "Data Source=" + filePath + " Persist Security Info = False; ";
}
But is this the only way to access multiple mdb files?

Read a large SQL script file in c#

I am trying to read a large script, thus far I have tried two options:
Option 1:
We can't open large script files in SQL management studio because of the issue of out of memory space, so Initially I used sqlcmd to execute 160 mb SQL script file on remote host, after 55 minutes some rows were effected with this error, TCP Provider: An existing connection was forcibly closed by the remote host. , communication link failure.
Option 2:
Now I am trying using this example, the file size is 160 MB with lot of insert statements, but Visual Studio crashes
Code:
public ActionResult Index()
{
string scriptDirectory = "e:\\";
string sqlConnectionString = "Integrated Security=SSPI;" +
"Persist Security Info=True;Initial Catalog=TestDB;Data Source=localhost\\SQLEXPRESS";
DirectoryInfo di = new DirectoryInfo(scriptDirectory);
FileInfo[] rgFiles = di.GetFiles("*.sql");
foreach (FileInfo fi in rgFiles)
{
FileInfo fileInfo = new FileInfo(fi.FullName);
string script = fileInfo.OpenText().ReadToEnd(); // here visual studio crashes
SqlConnection connection = new SqlConnection(sqlConnectionString);
Server server = new Server(new ServerConnection(connection));
server.ConnectionContext.ExecuteNonQuery(script);
}
return View();
}
Screen Shot:
I would suggest executing the insert statements line by line optionally wrapped in a transaction:
public ActionResult Index()
{
string scriptDirectory = "e:\\";
string sqlConnectionString = "Integrated Security=SSPI;" +
"Persist Security Info=True;Initial Catalog=TestDB;Data Source=localhost\\SQLEXPRESS";
using(var connection = new SqlConnection(sqlConnectionString))
{
var transaction = connection.BeginTransaction();
using(var command = connection.CreateCommand())
{
ProcessFiles(command, scriptDirectory);
}
transaction.Commit();
}
return View();
}
private void ProcessFiles(SqlCommand command, string scriptDirectory)
{
foreach(var file in Directory.GetFiles(scriptDirectory,"*.sql"))
{
using(var reader = new StreamReader(file))
{
while(!reader.EndOfStream)
{
var line = reader.ReadLine();
if(!line.StartsWith("GO"))
{
command.CommandText = line;
command.ExecuteNonQuery();
}
}
}
}
}
Keep in mind that this will put some pressure on the log file of the database.

Relative path not working while accessing a sqlite Database through C#

I am creating a Excel Addin through which i want to access a database. code is as follows
[ExcelFunction("My First Excel-DNA Function")]
public static string GreetFunction(string name)
{
GetConnection();
return "Hello" + " " + name;
}
public static void GetConnection()
{
//db = new SQLiteConnection("Data Source="+System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)+"\\Database\\XLSQLiteDemo.sqlite");
db = new SQLiteConnection("Data Source=Database/XLSQLiteDemo.sqlite");
try
{
db.Open();
cmd = db.CreateCommand();
System.Windows.MessageBox.Show("Connection created");
}
catch (SQLiteException ex)
{
System.Windows.MessageBox.Show(ex.ToString());
}
}
so when i give absolute path like c:/test/firstlibrary.../XLSQLiteDemo.sqlite it works.
but when i use relative path like db = new SQLiteConnection("Data Source=Database/XLSQLiteDemo.sqlite");
it throws an exception: unable to open database file error code 14.
the code which is in comment i.e.
//db = new SQLiteConnection("Data Source="+System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)+"\\Database\\XLSQLiteDemo.sqlite");
also doesn't work i.e. it calculates the absolute path but when i tried to debug; debugging is automatically terminated after db.Open();
and output in excel sheet is also #Value which indicates some error.
#adrino may be the "file" word in your string is the problem.remove it.
string relativePath = #"Database\XLSQLiteDemo.sqlite";
string currentPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
string absolutePath = System.IO.Path.Combine(currentPath, relativePath);
absolutePath=absolutePath.Remove(0, 6);//this code is written to remove file word from absolute path
string connectionString = string.Format("Data Source={0}", absolutePath);
this works on my machine.tell me if its correct.

Categories

Resources