If I add a property to my Entity for an existing column in the table, do I need to use Migrations? - entity-framework-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.

Related

EntityFramework Seed a table immediately after creation

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?

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.

Why does Database First EF skip mapping some tables?

I'm using Entity Framework 4 and with a Database First binding, and EF is not generating the entities for a few of my tables. I'm not getting any errors, and no matter how many times I select the tables to generate from the "Update Model from Database" popup menu on the design surface, the same tables are still missing from the model.
I get no errors in the wizard. They just don't get generated. Any clues?
EF requires a primary key on the table. EF will not map tables for which it can't find or derive a primary key. If all columns are nullable, it can't assume a primary key. If one or more columns are not nullable, EF will evidently derive a primary key for the table.
EF will ignore table without primary keys.
Options I can think of:
Did you check the box next to those tables?
Did you previously add them, then delete their entities but keep the cache of the tables?
If so you can remove them from entity browser window and re-add them
or manually add entities and define the table they map to in mappings window.
Perhaps tables were classified as relations instead of entities?
You can manually add the entities and choose the table they map to in mappings window.
Actually, in my case, it doesn't work because I was using a hierarchyid field as a primary key and EF doesn't work with this field type, so, it didn't import the table, because a valid PK is required.
A possibility is when you're using tables with some different field types, as hierarchy in SQL Server.
Without Primary Key Tables where Skip Automatically on EF, OtherWise You Fix a Value as Not Null.

Forcing a bridge/join table to become a many to many relationship in EF4

I have a simple database with 2 main tables with a many to many relationship through a 3rd bridge/join table.
This 3rd table has an extra field besides the two keys required, so that Entity Framework transforms it into a full entity rather than a many to many relationship between the other 2 tables.
I cannot change this third table in the database itself. Is there a way to ignore the extra field so that EF can do what I want, or a way to manually transform the bridge table into a many to many relation?
Yes, update the store schema (SSDL) to remove the additional fields and regenerate the MSL/CSDL. The easiest way to do this is to create your mapping with a DB which doesn't have these fields. It will work fine against the "real" DB at runtime.

EF4 - Is there any way it can be made to support unique indexes

My primary key is a guid column and I would like to have a unique index on another column in the table. I read that EF4 doesn't do anything for unique indexes. My question is: Can I add to a partial class any code that would allow me to check for non-unique values before my data hits the database. Currently I'm using the following configuration:
Users Desktop <> wpf Datagrid <> Observable Collection <> EF4 <> SqlCe database.
Thanks in advance.
Richard
I don't think it can do this, because to track value uniqueness entity framework requires all records from the table to be read into memory, or execute database query on each value change. It is performance-ineffective way and I think entity framework does not support this.
Supporting unique key concept is definitely in scope for the next version of EF from what i have heard. But uniqueness will be enforced at the objectcontext level meaning what is currently tracked in the object context. This is the same concept for cascading delete which currently works in EF4. In cascade delete, EF only enforces cascade deletes to entities that is currently loaded in the objectcontext. It does not try to load everything from the database.

Resources