EF code first won't recognize my DB - ef-code-first

The problem I'm facing is the following:
I've been happily developing using code first with Entity Framework 6 and my SQLServer 2014 DB, updating the database, extracting scripts and so far everything worked perfectly. The problem is that suddenly it lost the track of my database and whenever I try to add a new migration it says I have to update the database because it still has pending migrations to apply.
If I look at the database I'm working with it shows everything is there, even the __MigrationHistory table with every migration I'd done registered. Even though I accept code first recommendation and try to update the database. And no surprises here... The first table it tries to create throws an error because it already exists.
Could you please provide me some guidance on this?
Thanks in advance,
P.

I just figured it what was all about.
It happens that I changed the project name and the entire namespaces. The namespace of the migration itself is stored on DB so when I changed the namespace the Code First was unable to find it on the migration table.
Updating the ContextKey for every migration to the current namespace solved my issue.
Thank you for your time.

Related

EF Core Model Snapshot out of sync between add-migration and update

I'm using EF Core and code migrations. It's my understanding that the snapshot file is supposed to be the "target database" to build future migration files off of.
Situation:
1) I did an add-migration to create a migration after some changes. This updated the modelsnapshot which I guess is the expected behavior.
2) I then realized I realized I mis-typed one of my fields. Instead of a string it was supposed to be a byte[]
3) I made the changes to the classes
4) I did add-migration again.
Now the DataSnapshot seems to be out of sync because the new add-migration does not include this type file change.
It doesn't seem like I can do a remove-migration because no migration was actually applied to any database.
I know in EF6, this was a fine way to do it because it always targeted an actual database for the changes and not this snapshot file. So just deleting the change file and remaking the change file was good enough.
This is the second time I've had to make some change to a migration file after realizing there was an issue (without actually running the update against anything) and both times were just incredible pains to try to fix the issue without wiping out all my previous migrations and starting over.
My question is how do I handle this now? Should I be deleting both the change file and the snapshot file every time I do backtrack on an add migration?
I'm really concerned that I'm missing something here because now I have to make sure that not only is the change file correct but also the current snapshot is correct as well and if that snapshot ever goes out of sync, then I have to go and manually update it to
Probably have solved this by now, but I just ran into this.
Not sure if this is exactly the same issue, but this is how I understand it.
update-database is a DB action and updates your DB to current version or target migration.
remove-migration is an EF action and updates your migration stack and updates your snapshot.
To downversion I had to update database then remove migration down to the intended target.
At this point adding a new migration gave me the expected set of changes, where as before it was giving me none.
This appeared to do what I expected from EF doing update-database and update-database -target
The only thing I think you can actually do wrong in this case is delete your migration files before doing the update, because the down steps are indicated in the migration files, so it wont be able to complete this step if you remove the files. If you have the files, you can freely target migrations to set your current DB state.
I believe the confusing part is that the snapshot was previously used on every migration, where as now there's one snapshot for "last migration"

Different user for migrations

I'm trying to run
dotnet ef database update
When I do so, I get an error about not being allowed to CREATE TABLE. Not entirely surprising as I don't want the user I have the website running under to be able to create tables. So, after a bit of searching I found a solution that basically created an inherited context, and with that context used a different set of credentials. So, I tried;
dotnet ef database update --context ScaffoldContext
And I got the same error. I checked my connection string, yes, it's a user I can use to create a table with. Confirmed through SQL CLI. So, I added CREATE TABLE privileges to my site user, and the error changed. Suggesting that the base connection string was the one that mattered and it's ignoring using my elevated user. I tried moving the configuration into the OnConfiguring override in my inherited scaffold context, instead of services.AddDbContext in my Startup.cs. However, looking this up it looks like the wrong way to go about that. When I added CREATE TABLE privilege to my site user, I got a different exception about not being allowed to touch dbo.
This is driving me nuts, I don't want to use my site user as my migration user and it seems every example I find is from older versions of EF or dotnet core. Does anybody have any solid guides on how to go about managing users correctly using migrations with 2.1?
Note: If I change my connection string to be my sa user, it works fine. So the migration will go through. I'm just not wanting to give either full privileges to my site user or swapping credentials around in connection strings every time I need to run a migration.

EF Core running migrations from asp.net code throws exception

I am using EF core for the first time in my asp.net WebApi application (REST services),m using the SQLite provider. I have installed the Nuget package v2.0.1.
I have added my context , models etc, and everything seems to be working. I now wanted to try using Migrations. Following the documentation I have added my Migration, and all the expected files seem to have been created.
To test, I delete my SQLite database file and run the application,
however, when I call the `Migrate method in code, I get the following exception...
The weird thing is, when I close the debugger, the file and table is actually created. The migration table is present, but has no rows.
If I start again, ie delete the database, and then just run the migration from the Package Manager Console, then all works fine, ie I see...
PM> Update-Database
Applying migration '20180301030031_InitialCreate'.
Done.
PM>
an also the database is create, and this time the Migration table has the row of data I expect..
Any one have any ideas why this doesn't work when I just run it in code?
Thanks in advance for any help
[EDIT 1]
I get the same problem if I add a new Migration after just added a field. The first time I run, I gt the exception. If I then run again, it works!
I was considering just deleting this post, as the issue seemed to magically resolved itself.
I ran the same code (on the same database file) in a sample WPF application, and had no problems, so it seemed to be when running in the IIS process (and after doing iiresets to force the application to rerun the initialisation code which would then do the call to context.Database.Migrate();
At any rate, it now seems to work (but have no idea why it started working)

How can I remove issues with my flyway springboot project?

So while building a new database using our database migration scripts written in a springboot flyway project, we realized we made some mistakes.
Some old scripts need to be changed to ensure that we do not face these issues when we make a new database schema again. These issues are mostly related - an info table was not populated with entries in the project and there are scripts that refer to the data in the migration project -- this data does not exist because we never included a script to include data.
How can we correct this project - the only way I can think of is to correct scripts such that all inserts are replaced by - insert if not exists or replace create statements by create if not exists.
and then delete all entries in schema version and re-run this on all the database which are using this schema.
I cannot go back and correct my script because then the migration project will fail because of checksum issues.
You are rigth, if this project and the scripts are running in some existing projects you can not modify them because the checksum would fail.
Then the cleanest way I can think would be add a file called "DB-GENERAL-FIXES" or something like that, where you can add all SQL validations to restore the DB to a stable status. For the new implementations will be extra work first build it wrongly and then clean it, but if you are sharing the same code in production right now...is the best option

I can't write to a SQLLite database in my AIR app

I am publishing an AIR app in debug mode using FlashDevelop and have included a database in the files/folders to be published.
When the app first launches it checks whether there is an instance of this db in the applicationStorageDirectory, if there isn't it copies the included one from the applicationDirectory to the applicationStorageDirectory.
This should mean that the referenced database dbFile = File.applicationStorageDirectory.resolvePath(DB_FILE_NAME); should now be writable, however when i run the app i can read the records from the table but when i attempt to write using an SQL statement I get an SQLError: 'Error #3122: Attempt to write a readonly database'.
I know that this would be thrown if i was attempting to write to the read only location of the applicationDirectory but i'm certainly using the File.applicationStorageDirectory location which should (as far as i know) be writable.
The location of the db on my Windows 7, 64bit = C:\Users\sean.duffy\AppData\Roaming\FishFightAppData\Local Store\db this is found using the dbFile.nativePath property so again i'm sure i should be able to update the db.
Anyone got any ideas? I have tried everything i could think of and searched all over but the only common cause seems to be when people try to write to the asplicationDirectory and not the storage directory....
UPDATE::
My bad - have just realised that i've misread the API of the 3rd party library i'm using! I should have been calling executeModify(statement) which can modify the contents of the db, instead i'm calling execute(statement) which doesn't/can't overwrite the db.
The source code is compiled into a swc and there was no documentation to point out you needed to use executeModify, although i should have guessed from the name i suppose!
Sorry about that and thanks for your help
(As a public courtesy to get this off the unanswered list, I am reposting the apparent solution. As usual, the asker is more than welcome to ignore mine and post it themselves and accept their own answer.)
In this API, you need to call executeModify(statement), not execute(statement). The latter does not overwrite the database.

Resources