How to access context after each Entity Framework db migration - sql

When I Add-Migration, I get the appropriate DbMigration class with the Up / Down methods, where I am able to make schema changes and (with the use of the Sql() method) can make data/content changes as well.
I'd like to be able to make content changes per migration using the database context. I understand that I could use the Seed method in a Configuration class, but my understanding is that I can only wire up one Configuration with my initializer.
I'd prefer to have a UpCompleted()/DownCompleted() methods that would provide access to the db context after the migration completed. This would enable writing incremental data/context change "scripts" in a manner that would be less prone to errors than using the Sql() method.
Am I missing something? Is this possible?
Thanks!

That doesn't really work because the context only has your most recent model - which can only be used to access the database once the most recent migration has run (which is effectively what Seed achieves).
For an example of how this idea breaks, if you moved a property from one class to another then seed logic from older migrations would no longer compile. But you couldn't change it to use the new property because the corresponding column wouldn't exist in the database yet.
If you want to write this kind of seed/data-manipulation logic, you need to put it at the end of the Up/Down methods and use the Sql method to perform it using raw SQL.
~Rowan

Related

Do I use Snapshot file, migration file or data annotations in my EF Core to update database?

I'm trying to understand the different types of migration paths we can choose when developing an ASP.NET Core 1.0 application with EF Core. When I created my first Core application I noticed it generated a ApplicationDbContextModelSnapshot class that uses a ModelBuilder to build the model.
Then I read that if I need to add a table to the database, I need to create the new model and run the command line to generate the migration file and update the database. Ok, I get it up to this point.
But when I do that, I notice that the ApplicationDbContextModelSnapshot class gets updated too.
1) Does that mean I cannot modify this ApplicationDbContextModelSnapshot class since it looks like it gets regenerated each time?
2) Should I use Data Annotations to build my model or should I use Fluent API which tells me to build my model in the ApplicationDbContext class? Huh? another file that builds the model?
I'm seeing three different ways of working with the database here, the snapshot class, data annotations, and fluent API. I'm confused because today, I made a mistake in my last migration file so I deleted the file, dropped the database and reran the database update.
But by doing that I got errors similar to:
The index 'IX_Transaction_GiftCardId' is dependent on column 'GiftCardId'.
ALTER TABLE ALTER COLUMN GiftCardId failed because one or more objects access this column.
So naturally I was wondering if I had to modify the ApplicationDbContextModelSnapshot class.
What is the path I should be taking when it comes to migrations or database updates because these three paths are confusing me.
I have run into this issue before when I create migrations, make model changes, create new migrations, and try to update the database. The root cause is when keys are being changed and relationships are not dropped and are not added back or do not exist.
You have two options
Easy Method
The easiest way is also the most destructive way and only possible in a dev environment.
Delete all migrations, drop the database, create new migrations and run 'update-database'.
Hard/Safest Method
This is the most time consuming method. I recommend do this in a local integration branch first, pushing it to a remote integration, and then production.
Open the migration file, ie 20160914173357_MyNewMigration.cs.
Drop all indexes in order
Drop/Add/Edit table schemas
Add all indexes back.
For either method, just be sure to test and test again.
Do not modify ApplicationDbContextModelSnapshot. It is a design-time artifact, and should only be modified in the case of a merge conflict.
To update the model, always use data annotations or the fluent API.
For more information on the EF Migrations workflow, see Code First Migrations. It's for EF6, but most of the information is still relevant.

Single FakeApp for all test in Play Framework

I want to have single FakeApplication for all my test.
My final goal is to set up database and use it in all test. They should access single database and share data in it. I can not use H2, because I use some MySQL features(fulltest search, for example). But if there is no started application, I can't call "DB.withTransaction" because there is started application yet. But it should start once, because it drops all tables and create new ones.
How can I do it?
I am using scala and JUnit. I solved my problem next way: I just created singleton for my fake application, which is retrieved as an implicit val. So, all work about creating and cleaning database is done on first fetch.

Does liquibase give access to java.sql.Connection for custom tasks

Is there a way of having liquibase call a custom Java class/plugin and giving that class access to the underlying connection to make data changes. I had a look but it only
So of our update steps require extensive data manipulation which is far far easier to do and debug in code than using SQL. So I would want to write tasks that can extract, transform and save data. Is that possible within the liquibase framework?
If you are using a subclass of Change using the extension framework (liquibase.org/extensions) the generateStatements() method is passed the Database object the change is being executed against. Calling
((JdbcConnection) Database.getConnection()).getUnderlyingConnection()
will return the java.sql.Connection used.
If you are using the CustomTaskChange interface, the execute() method that is executed is passed the same Database object you can get the connection from.

Should I use Get or Load - nhibernate?

I am wondering which one I should use in this situation. I have a dropdown list that send a value back to the server. The server currently uses load and make the object. It then grabs a value out of and tries to convert it to an enum.
After doing some reading it seems that I should just use Get as I am need to access something out of the object other than the PK.
In general, use Get if you need access to properties other than the Id itself; this makes the intention of your code much clearer and is likely more efficient in the long run. Load is great if you need to setup FK relationships when creating or updating entities without making unnecessary round-trips to the database.
For further reading, check out Ayende's article that describes this in greater detail.
Get and Load are different if lazy loading is enabled.
If you use the method Load, NHibernate does not retrieve the entity from the database, but rather creates a proxy object and the only populated property is the ID.
If you access to an other property, NHibernate will load the entity from the DB.
So in your case the best use should be Get.

Unit Testing the Data Access Layer - Testing Update Methods?

I'm looking into adding some unit tests for some classes in my data access layer and I'm looking at an update routine that has no return value. It simply updates a row based on the id you provide at whichever column name you provide.
Inside of this method, we collect the parameters and pass them to a helper routine which calls the stored procedure to update the table.
Is there a recommended approach for how to do unit testing in such a scenario? I'm having a hard time thinking of a test that wouldn't depend on other methods.
Test the method that reads the data from the database, first.
Then you can call the update function, and use the function that was tested above, to verify that the value that was updated is correct.
I tend to use other methods in my unit tests as long as I have tests that also test those that were called.
If your helper functions are in the database (stored procedures or functions) then just test those with a DatabaseUnitTest first, then test the visual basic code.
I would just use a lookup method to validate that the data was properly updated.
Yes, technically this would relay on the lookup method working properly, but I don't think you necessarily have to avoid that dependency. Just make sure the lookup method is tested as well.
I would use the method to get that data and check the return value to what you updated and Assert the expected value. This does assume the method used to retrieve the data has been tested and works correctly.
I use nhibernate and transactions and for unittests I don't commit to the database but I flush the session which gives the same errors if needed but doesn't write the data.
Of course if you have a build server you just run the unittests against a freshly made database which is freshly made on each build. Try using an filebased database like firebird or something.