EntityFramework Seed a table immediately after creation - entity-framework-6

I'm using EF6 Code First Migrations and ran into an issue where I created a new lookup table (Lookup) and established a required foreign key relationship with it (Table).
The (Table) already has records in it, so after adding the column I am backfilling the existing records (before the AddForeignKey method) with a default value to satisfy the required field requirement.
I have the (Lookup) table filling with Data in the Seed process.
The issue I am having is that when I run my code first migrations, I am getting a foreign key constraint error because in the migration Up code I am creating the foreign key relationship with the (Lookup) table and backfilling the records using the Sql command. But since the Seed method hasn't run yet, the (Lookup) table has no values in it, so the constraint fails.
Is there a way to execute that Fill without being redundant with the code in the Configuration.Seed method?

Related

How to avoid primary key column duplication in PostgreSQL v 10?

I am running a script to update a table structure, my problem is with the primary key column (id), the query creates a new id column each time I run my script.
This the first time that I am trying to write a script to update a database structure.
The database was created by an old version of an application,and now we want to release a new version of the application, but to achieve this goal I wrote a script which in summary is creating tables if they don't exist, adding columns to the tables if they don't exist, deleting old indexes and creating the new ones, etc.
The problem happens when the scripts add the primary key in the tables, in the database, the tables have a primary key column of type integer. But my query is not detecting this primary key column and it creates a new column with the same name and data type, at least that is what I see in PGAdmin v4.8.
Originally the primary key columns were created using the type serial and then PostgreSQL automatically creates a sequence and use it for the primary key.
How can I avoid the duplicated primary key columns?
Originally the column was created like follows
create table mytable(
id serial,
.
.
.
);
And if I look in the table, the column looks like this, which means that PostgreSQL created a sequence mytable_id_seq and used it for the auto increment value of primary key column.
id integer NOT NULL DEFAULT nextval('mytable_id_seq'::regclass)
But after I execute the following query and look in the table, it has a new column with the same name and data type like the one in the previous lines.
ALTER TABLE public.mytable ADD COLUMN IF NOT EXISTS id serial;
I am expecting to see only one column no matter how many times I execute the query.

Where should I write the script that fills new data in my updated schema?

I am working on a web app that already has a schema in place (aka in prod) with a certain number of tables (A, B, C...).
Table A has an attribute that corresponds to an enum from table B. Problem is that I can have only one item of that enum list in my dedicated column in table A. But I want my objects from table A to have many of them. So I created a join table A_B and a has_many through association with my table B.
The first consequence is that I need to fill my join table with data from the previous schema architecture. To be clearer, they were objects from table A that were associated with one element of the table B enum. I need to report these simple relationships (only one element from enum list in table B is associated with table A objects) in my newly created join table.
Here's the type of things I'd like to do:
list_of_ids = []
Model_A.where(attribute: 0).each { |r| list_of_ids << r.id }
a.each { |el| A_B.create(tableA_id: el, tableB_id: 0) }
Where should I write and execute these lines of code that will update my data ?
As stated in my comments, I would put this "data-update" logic in the same migration file of the join table creation.
Why in a migration file?
the data conversion needs to be done only once, AFTER you created the join table and BEFORE you remove the column which holds the foreign key. If you do this data conversion after the column removal, you will get an error saying that your code is trying to access column that does not exist anymore.
the migration is responsible for changing the DB structure AND for the data integrity.
Why not a rake task?
rake tasks are meant to be run several times, not only once. The usual tasks are "send_emails", "update_expiration_dates", "compute_cache", "close_inactive_users_account", etc.
the data you have before your conversion has_many -> HABTM have to be updated to follow the new structure. the rake task could not be ran, and then your data would not be updated, therefore you would loose the association between your models (removing the foreign_key column before running the rake task would make you loose this data).
your data-conversion logic must happen after the migration creating the join table and BEFORE the migration removing the foreign key's column. There are clear way to say to your rails app: "do this migration, then stop, run this task, then do this migration". It will run the migrations consecutively. If you have these 2 migrations pending, they will be run at once unless you specify otherwise (which is not common at all), and then you rake task will be useless because it relies on the fact that the foreign key column still exists.
In addition to MrYoshiji's answer (too long for comments):
Migrations are intended for one-off changes to both database schemas and the data therein. The official guide mentions this, too.
In your case, populating the join table is an appropriate thing to do in a migration. Otherwise data would be left in an invalid or incorrect state vis-a-vis the schema and model changes you have made. Running migrations is a typical step in deploying a Rails app. Since you probably do not want to deploy without updating the data, having it as part of a migration is a great solution. In contrast, if you created a custom rake task to update the data then you would need to remember to run it manually after deploying or add it as a deployment step, neither of which is a very good option.

Model/Migration creation order matters in Rails?

I have generated 4 models in rails. Now some of them requires columns for foreign keys from each other.
Suppose I have a table User and other table Post. Now do i need to generate the models in order for ex. User and then Post, so that Posts table could contain user_id column in it?
I am not running rake db:migrate now. What I'm doing is generating models and specifying the columns that might be necessary.
I want to know is, does rake db:migrate takes care of the order automatically and i can create the models in any order? Or as migration files has timestamps attached to it in the file name, it will be processed according to the order of its creation and will give me the error for ex. user_id foreign key dependency, table Users not found?
There are no foreign key dependencies in Rails migrations, so as long as you are not creating dependent data for the models in the migrations, it will work correctly.

If I add a property to my Entity for an existing column in the table, do I need to use Migrations?

Using Code First EF6, the database table already includes a column that the Entity does not (I previously only accessed it as a navigation property). Now in order to hopefully speed up performance, I want to add the other, existing column so I can use in in my predicates. Do I need to worry about using migrations?
Yes and no. You don't need to use migrations to create the column, obviously; however, EF may still see it as a mismatch between the model and the DB, because it bases its knowledge off of what's in the __MigrationHistory table. Try scaffolding the migration, and if it wants to add the column, call Update-Database -Script, then execute just the INSERT INTO __MigrationHistory part in order to convince EF that your DB is up to date.

Cascade Delete, same table, Entity Framework 4 Code First

Hi Im currently working with .sdf database (Server Compact Version 4.0) and sql express. I'm trying to setup a cascade delete on a same table (category - sub category) but I get that I cant add relation to the same table.
A foreign key constraint had and
update or a delete cascade rule, and
self-references a column in the same
table, is not allowed
What can I do about this?
EDIT
I'm the only one with this problem?
As your SQLException suggested, this is a limitation of SQL Server in general and has nothing to do with EF or Code First. Basically, SQL Server does not allow creating cascade actions on Inner relationships – when the cascade path goes from column col1 in table A to column col2 also in table A. A->A.
In fact, Code First was trying to use Declarative Referential Integrity (DRI) to enforce cascade deletes and SQL Server throws.
The only way to enforce cascade deletes for this relationship is to use Triggers. You can write a Delete Trigger on the category table that either deletes the dependent rows or sets all corresponding foreign keys to NULL (based on your requirements).

Resources