Delete and create database from seed method? - c#

Every time I do update-database -v -f I want my database to be fully dropped and then created empty again. Is it possible to do?
I tried to delete it and then create it but it doesn't work. Strange thing that I did exactly same thing in EF4 and it did work, but now it does not.
So how can I re-create my database using some command?
Migrations is enabled for context 'MainDataContext' but the database does not exist or contains no mapped tables. Use Migrations to create the database and its tables, for example by running the 'Update-Database' command from the Package Manager Console.
This is my seed method
protected override void Seed(Api.Models.MainDataContext context)
{
context.Database.Delete();
context.Database.Create();
// context.Database.Initialize(true); Also tried this but same result
}
Note: Truncate with raw queries does not work, too many relations.
Note: Delete all objects is bad idea, too many objects.

Could you perhaps first run the Update-Database like so:
Update-Database -TargetMigration:0
That would roll all migrations back to zero. And then run Update-Database again.
Edit: The seed method should not do anything to database structure, it should only modify the data. Migrations should be used instead.
Edit2: I can't find information on deleting the database with Update-Database, it will only rollback until first migration, which you seem to have none.
Only when deploying it through code, you can use DropCreateDatabaseAlways-strategy like so: http://www.entityframeworktutorial.net/code-first/database-initialization-strategy-in-code-first.aspx
If you will do the migration manually, you'll probably have to manually remove the database before running Update-Database.

Do you want to drop and recreate the database when the model changes? How about...
Database.SetInitializer(new DropCreateDatabaseIfModelChanges());
You are right, EF6 has changed the way migrations are handled.
You will have to delete your Migrations folder and all the classes in there.
#cederlof is right about update-database: there is not a drop database switch, or a create database switch. The only wan (AFAIK!) to create a EF6 database is to do new CloudMinderDataContext(someconnectionstring)
I had a problem because I wanted migrations to update my staging database but could not then create a new database in code. This was fine in EF4 but not in EF6. I had to use SQL to create database, then migrate it...
How do I generate an EF6 database with migrations enabled, without using update-database?
and
http://softwaremechanik.wordpress.com/2013/11/04/ef6-if-migrations-are-enabled-cannot-createdatabaseifnotexists/

Hi Steve: To drop one database use this. If you are integration testing your tests might actually run in parallel so be sure you've finished with this database before calling this...
private void DropDatabase(string connectionString)
{
var bld = new SqlConnectionStringBuilder(connectionString);
var dbName = bld.InitialCatalog; //database you want to drop
bld.InitialCatalog = "master";
var masterConnectionString = bld.ConnectionString;
using (var cnn = new SqlConnection(masterConnectionString))
{
using (var cmd = new System.Data.SqlClient.SqlCommand())
{
cmd.Connection = cnn;
cnn.Open();
cmd.CommandText = string.Format("ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE",
dbName);
cmd.ExecuteNonQuery();
cmd.CommandText = string.Format("DROP DATABASE {0}",
dbName);
cmd.ExecuteNonQuery();
}
}
}

Related

How to create the SQlite database when the application is deployed/installed?

I am new to c#/.NET and developing an application with SQlite datbase and entity framework and it is all working fine during testing. I am specifying the below for the filepath to the .db file.
var path = AppDomain.CurrentDomain.BaseDirectory;
On deployment I need the application to create the database fresh, that doesn't contain the test data I was using during development. So I cannot simply copy the current .db file. Can anyone help with code that checks existence of database, and if not it will create new?
You can use this method:
private static void CreateFreshDb(string dbFilePath)
{
// Create the DB file
SQLiteConnection.CreateFile(dbFilePath);
// Create a table
var connectionString = $"Data Source={dbFilePath};Version=3;";
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
string creationScript = "Create Table Person (Id int, Name varchar(20))";
SQLiteCommand command = new SQLiteCommand(creationScript, connection);
command.ExecuteNonQuery();
command.Dispose();
}
}
And call it like that:
string dbFilePath = "C:\\Db\\Database.db";
if (!File.Exists(dbFilePath))
{
CreateFreshDb(dbFilePath);
}
Note that I use the System.Data.SQLite library here.
An appliation that creates databases should be in principle a script that creates databases. If you application has its own business line which requires a database, but it is not intended to create a database at first, better you create it manually outside the code and then simply let the code choose between which database to use between testing and production, via appSettings or similar solution.

Completely delete EF database in c#

I've been messing around with changing my object properties, and that requires me to keep updating my table, but I keep getting errors, so does anyone know how I can just delete the whole DB and start over?
I have this code
using (var ctx = new Context())
{
foreach (Item2 block in new_Items)
{
ctx.items_db2.Add(block);
}
ctx.SaveChanges();
test = (from b in ctx.items_db2
orderby b.Index
select b).ToList();
}
I've tried truncating the table but I can't do that since I've changed the object properties, and even when I run the commands from the package manager console to update the table, I get other errors so I'd just like to start from a clean slate.
You can do it from from your code just by running:
using (var ctx = new Context())
{
ctx.Database.Delete();
}
Alternatively connect to your database using VS - View --> SqlServer Object Explorer connect to your database server, right click on the database you want to delete and select Delete. You want to check the checkbox to close existing connection otherwise deletion may fail.
If the migrations are not important, I:
Delete migrations.
Delete all the tables in the database.
Run the Enable-migration command.
Run the Add-migration command, to add an initial migration.
Run the Upgrade-database command. This will rebuild all the tables in the db, and you back to square one :)
I use code first.

DROP command denied to user X for table 'Y'

We are getting ready for a big SQL migration.
Currently, I have the code written, and I am testing it out with data on my local machine.
Step 1 is to throw out the existing data in the table before I import the new stuff:
using (var txn = m_mySqlConnection.BeginTransaction()) {
using (var cmd = new MySqlCommand("TRUNCATE TABLE `blah_blah`;", m_mySqlConnection, txn)) {
cmd.ExecuteNonQuery();
}
// other code
}
But, the TRUNCATE command is throwing an exception whenever I try to execute it with the MySQL user account I am running the code with:
I tried going into MySQL Workbench to give this userid DROP permission, but all I could find was a way to add DROP under the View section.
I tried that, but it did not work.
How do I go about giving this user the ability to remove the data in these tables so that I can test my populate script?
TRUNCATE deletes the table. Try using DELETE FROM Table.

Restore and Backup with Entity Framework

I use C#, .net 4, Entity Framework and SQL Server 2008 R2 in a project.
I have no familiarity with backup and restore from database by Entity Framework. Please help me to write restore and backup code in Entity Framework
Entity Framework is an ORM - object-relational mapper - designed to handle interactions with single entities and/or short lists of entities. It's neither designed for bulk operations, nor is it a server admin framework. So no - I don't think you can do this using Entity Framework - that's not its job.
Use an appropriate tool for the job! Either use SQL Server Management Studio to handle backup/restore - or if you must do it programmatically, use the SMO (Server Management Objects) which is intended for exactly these kinds of jobs
To other friends who have this problem ....
Useing ExecuteSqlCommand can backup of db in EF 6+ .
For example : (this code create backup of your DB , I had tested this.)
string dbname = db.Database.Connection.Database;
string sqlCommand = #"BACKUP DATABASE [{0}] TO DISK = N'{1}' WITH NOFORMAT, NOINIT, NAME = N'MyAir-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10";
db.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction, string.Format(sqlCommand,dbname, "Amin9999999999999"));
backup saved in C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\Backup
ref=> https://entityframework.codeplex.com/discussions/454994
but I do not recommend for working with this method!
I strongly recommend the use of the article below:
http://www.c-sharpcorner.com/Blogs/8679/backup-and-restore-the-database-in-Asp-Net-web-application.aspx
This should get you going on the restore side:
void LoadDB(
System.Data.Entity.DbContext context,
string backup_filename,
string orig_mdf, // the original LogicalName name of the data (also called the MDF) file within the backup file
string orig_ldf, // the original LogicalName name of the log (also called the LDF) file within the backup file
string new_database_name
)
{
var database_dir = System.IO.Path.GetTempPath();
var temp_mdf = $"{database_dir}{new_database_name}.mdf";
var temp_ldf = $"{database_dir}{new_database_name}.ldf";
var query = #"RESTORE DATABASE #new_database_name FROM DISK = #backup_filename
WITH MOVE #orig_mdf TO #temp_mdf,
MOVE #orig_ldf TO #temp_ldf,
REPLACE;";
context.Database.ExecuteSqlCommand(
// Do not use a transaction for this query so we can load without getting an exception:
// "cannot perform a backup or restore operation within a transaction"
TransactionalBehavior.DoNotEnsureTransaction,
query,
new[] {
new SqlParameter("#backup_filename", backup_filename),
new SqlParameter("#database_dir", database_dir),
new SqlParameter("#new_database_name", new_database_name),
new SqlParameter("#orig_mdf", orig_mdf),
new SqlParameter("#orig_ldf", orig_ldf),
new SqlParameter("#temp_mdf", temp_mdf),
new SqlParameter("#temp_ldf", temp_ldf),
}
);
}
If you don't know them beforehand, the MDF and LDF LogicalName values can be obtained manually or programmatically from a query like this one:
RESTORE FILELISTONLY FROM DISK #backup_filename

Creating Sqlite Embedded database from application

I have a winforms app that uses sqlite to store data. Instead of shipping a blank database, can I use scripts to create the tables the first time the user uses the app? Can you point to a C# example?
Update: I want to avoid shipping a blank database. So if a user install the app for 1 user only, only his profile gets a copy. All users profile gets the database if the install is for all users.
Yes, this is possible:
When the application first runs, check if the database file exists.
If it doesn’t, open it with the Sqlite option FailIfMissing=False. This will create a new file.
Then, use SQL commands like CREATE TABLE ... to create the schema structure.
For the second step, I use code that looks something like this:
public DbConnection CreateConnectionForSchemaCreation(string fileName)
{
var conn = new SQLiteConnection();
conn.ConnectionString = new DbConnectionStringBuilder()
{
{"Data Source", fileName},
{"Version", "3"},
{"FailIfMissing", "False"},
}.ConnectionString;
conn.Open();
return conn;
}

Categories