EF Code First deployment - asp.net-mvc

I have an MVC code-first application that creates a database based on my schema. On the production machine, we will need to first create the database (empty, with no tables), so that we can assign the proper username and password to my dbcontext in the connection string. Considering that the DB is created on production, what should my code do?
I can't use DropCreateDatabaseIfModelChanges because a DB will already be created with no Metadata.. and can't use DropCreateDatabaseAlways because I need it created only the first time.
I also tried this:
if (context.Database.Exists() && !context.Database.CompatibleWithModel(false))
context.Database.Delete();
if (context.Database.CreateIfNotExists())
but context.Database.CompatibleWithModel(false) return always TRUE on an empty database for some reason...

You might need to deploy the database schema via SQL script manually. You can generate the script from your production database instance.

Related

Duplicate postgres schema

I'm working on multi-tenant system in which I need to work on different tenats. in some cases I need to create new schema which contains some tables and default data. for that I just want to duplicate or copy public schema with diff. name Is there any way to duplicate or copy it.
I did work around on this problem but I want a solution to copy schema not to create schema and regenrate table and data
Take a back up of the schema you want along with the data In a plain text SQL file using pgadmin. And then create new schema and execute the SQL file under the new schema.

How to export the DDL of domains(Database schema) of new version for update

I have developed a application with Grails earlier.Now as per new requirement there is a need to modify the existing domain classes as well as adding a new classes and changing / establishing new relationship between the as well.
Now the new requirement has been implemented and I am going to deploy to production environment. however, the DBA want a script change the production database DDL. DBA is not allowing the auto create / update of database schema while bootstrapping the application.
I know how to export DDL of for creating tables. but that script will drop tables which means all data will be lost.
But I don't know how to export DDL for DDL-update (no drop tables/recreate tables). Anybody has good suggestion ?
You can not expect the existing data to get stored according to the new database schema as is.
For example, you have a table Sample with the contactNumber field with the nullable : true constraint in your existing schema and in your new schema this constraint has been changed to nullable : true & unique : true.
In such cases database will fail to keep the existing data intact or adapt to new schema.
To preserve the existing data, you may have to go through a tedious process like -
Take backup of the existing database.
Make a note of the modification you have made to the existing Domain classes.
Find out which modifications may lead to failure / data loss.
Drop the earlier database schema & Deploy the new application and let it create the database schema.
Write a script or utility which will process & store the data from database backup according to new database schema.Make sure the utility you have written has the capalibility to handle the modification(constraint, field added, field removed) done to the database schema.

Where is that file on my system?

Am trying to learn ASP.NET MVC and search the internet in and out including SO. A lot of questions and answers about |DataDirectory| as where and how.
When debugging the site breaks:
"The model backing the 'ASPNETDBContext' context has changed since the database was created...".
Then I checked the path: |DataDirectory|ASPNETDBContext.sdf
string path = AppDomain.CurrentDomain.GetData( "DataDirectory" ).ToString();
It points to the App_Data of the project but no file there.
The DB is entirely empty so deleting the thing is all I need.
My actual question I need to be answered: How to fix this properly?
made a follow-up: And additionally: Where is that file!
The answer to your problem lies in reading Scott Guthrie's blog
For those who are seeing this exception:
"The model backing the 'Production' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance."
Here is what is going on and what to do about it:
When a model is first created, we run a DatabaseInitializer to do things like create the database if it's not there or add seed data. The default DatabaseInitializer tries to compare the database schema needed to use the model with a hash of the schema stored in an EdmMetadata table that is created with a database (when Code First is the one creating the database). Existing databases won’t have the EdmMetadata table and so won’t have the hash…and the implementation today will throw if that table is missing. We'll work on changing this behavior before we ship the fial version since it is the default. Until then, existing databases do not generally need any database initializer so it can be turned off for your context type by calling:
Database.SetInitializer<Production>(null);
Hope this will help you resolve the issue.

Best way to import data into my new rails app?

Hi I have a sqlite3 database full of data from my previous version of the web app which WASN'T written in rails. Im now rewriting the web app in rails from scratch. But Id like to use the data from my previous app in the new rails app. Whats the best way to accomplish this?
This is what Ive tried so far and it didn't work very well:
1) I created a new rails app
2) replaced my sqlite3 database in the new app with the sqlite3 database from the old app
3) Created a model with the same schema as the old DB.
4) changed the databse.yml file with the updated DB file details
5) un my model added the "establish_connection" method
6) I could thus get it to show me all the details of the old database in my browser #"index.html"
7) However, I ran into problems when wanting to insert/edit records into the DB. Since the DB did not have a primary key column for each row, it didnt work.
8) So I tried to do a migration to add a column with a primary key . It didnt work
9) suddenly a new development.sqlite3 database had shown up in the app and it was trying to add a primary key to the NEW DB.
10) So I just deleted the new DB that had popped up and after that the app wasn't working
11) Now I want to start from scratch and so my question:
"Whats the best way to import data from a previous non-rails app (in a sqlite3 DB format) into a new rails app"
You want to be working with 2 databases, the old and the new. So, your database.yml needs to have 2 connections in it. One should be your normal connection called development or production and the other should be called legacy. Fill out their different connection information. By default, your ActiveRecord models will pull from the one not called legacy.
Create a model called LegacyBase. In the model put establish_connection "legacy". Now create a directory at app/models/legacy. Put all of the models represent data from the old DB inside this directory. All of those models should extend from LegacyBase. This will mean they're all reading from the old DB.
Create your new models. Do you want them to have a primary key column? If not, see this answer. Create an ActiveRecord database table with no :id column?. They will by default have an id column, though and I recommend leaving it that way.
For each of the legacy models, write a method called to_model. In this method, write the code that creates a new object and populate it with the old data and save it. Something like this:
class OldUser < LegacyBase
establish_connection "legacy"
def to_model
User.create!(self.attributes)
end
end
You can do any logic that needs to happen to make the old data fit your new app. Call this method on all of the old records like OldUser.all.map(&:to_model).
Do this for all of the tables that you want to move over.

Migrations with EF. Where they are stored?

Yesterday i was absolutely sertain that all migrations data for EF placed in classes, placed in my solution as nested from DbMigration. But today i was dig a slightly deeper(just try to fallback to old migration with enable data loss not with nu-get and visual studio, but with code())
DbMigrator fg = new DbMigrator(new Settings() { AutomaticDataLossEnabled = true});
fg.Update("MigrationName");
And get exception, smth like "string should be truncated", those means that migrator tried to update column from big to small MaxLength attribute. So, i had excluded migration that caused this update and move this changes to migration, those create tables. The error still was occured. I got to intellitrace and it said that those(deleted) migration still was called. Looking to requests told me things like this:
SELECT [Extent1].[MigrationId] AS [MigrationId] FROM [dbo].[__MigrationHistory] AS [Extent1]
Looking to a table __MigrationsHistory and get my deleted migration there with field model that contains crypted data(don't decrypt this yet) . I was realy shocked. Does this means that all code, have written in classes is just the fake and really executed code placed here? And does anyone know, how to work with this table, register projections of migration classes to it etc. Or the once way to work with migrations is nu-get console?
I am not fully sure what your primary question is, so I will first try to answer last part about __MigrationHistory table.
Code in classes is not fake, your code in classes is compiled and run.
This table, however, really contains your database model, but it is not encrypted, it is compressed. The reason why Migrations API needs to store your model, is to be able to compare it against your current actual model and track changes for you (for example when you add a new property it will be able to tell what property you added and to perform automatic db migration).
In previous version of EF there was an EdmMetadata table where hash of your model was stored, and EF was able to detect if you made some changes to model by comparing stored and current model hash value. New version when migrations are enabled stores entire model as compressed blob, so it can do diff between the model that was used to create database and current model you are using, and make automatic migrations accordingly.
You should not work directly with this table, it is automatically populated by migrations API, but nuget console is not the only way to do migrations, you can check this resource for some insights how to do it from code.
Now, regarding your question from question title (where they are stored?), migrations are stored in code, in a class inheriting from DbMigration class that migrations API creates for you when you do Add-Migration command in nuget console. When you perform an migration (Update-Database), either from nuget package manager console or from code, API will compare your current model with versions in __MigrationsHistory to find initial version (if you have not specified it) and perform all migrations in between initial and target version (if not specified otherwise target is latest version).
I'm not really clear how you did exclude your migration that causes problems, as you need to migrate your database to version before that migration, and then delete and recreate all subsequent migrations from there.
Maybe you could solve your fallback to old version problem by implementing public override void Down() method in your migration that causes problems when trying to rollback? This method can be used to execute code which performs inverse any operations for migration.
Not directly related to question but worth mentioning, there is also pretty detailed tutorial here for EF CF.

Resources