Entity Framework Core, DB First. Beginner questions about losing data accidentally - ef-core-3.1

I haven't written a single line with EF Core yet but I have been reading tutorials and trying to get a grasp of the concept first. I have not been abl to find any answers to these questions regarding losing data accidentally:
Using Database First, if I wrote the database model by hand and forget to add some tables as DbSet objects in the DbContext, are the missing tables DROP'ed on SaveChanges?
If a DbSet is left empty and SaveChanges is called, will all the rows in the corresponding table be DELETE'd?
In general are there any pitfalls that could lead to data loss by mistake or if you forget to do something, or do all hard delete actions require explicit code?

I have reformulated the questions a little, to avoid misunderstandings.
Are the tables that aren't in my DbContext dropped on SaveChanges?
The tables will only be deleted if you drop the database or otherwise delete the tables.
If a DbSet is empty and SaveChanges is called, will the rows of the corresponding table be deleted?
Yes. Otherwise the framework wouldn't work.
Are there any pitfalls that could lead to data loss by mistake or if you forget to do something
It depends on what you mean by mistake or forget to do something. If you forget to save your changes, then your changes will be lost. If you, by mistake, modify, delete or drop tables, then of course your data will be lost.
You should always backup your database regularly, test that the backup can be restored, and test new things on a copy of the database.

Related

Is database deletion through Entity Framework permanent?

I have a web application using EntityFramework and an Azure SQL Database. I would like to know if deleting a row in the database removes the information permanently or simply marks is as deleted but it still be accessed if needed?
db.MyTable.Remove(objectInstance);
db.SaveChanges();
Is this someting that can be configured or do I need to implement this feature myself adding a deleted attribute?
The reason I want this is to be able to perform analytics including objects that might have been already deleted
EF has nothing to do with this actually. Whether records are deleted permanently or not is actually up to the RDBMS. EF is an ORM for the RDBMS.
Options IMO:
You manage the records marked as deleted using an extra column
You can move the deleted records to another table or file whichever is convenient for you to run analytics on. That way your queries will have to touch less number of records and be faster.
You can go through the log files and execute the INSERTs again to get the deleted records.
Hope my suggestions help you in right direction.

Hiding a bad database schema behind neater domain POCOs

I'm working on an application that interfaces with a slightly odd database. The design of this database is pretty bad; there are basically no foreign keys (although there are columns that reference other tables, they're not set as keys), columns are named very ambiguously, and the structure does not lend itself to the kind of logic I'm aiming to do (mostly, it forces joins for operations that should be simple, and leaves you trawling through needlessly massive tables for things that could have been split).
Unfortunately, I'm stuck with this database. It's being replicated off a third-party system, so I can't change the table structure or anything. I can add stored procedures and views, though.
In the application, I've come up with a set of classes that I can work with much more easily. I've got quite a bit of experience with Entity Framework, so I'm planning to use that. My initial hunch is that I can add views to the database that return things in the format of my classes, and then from there on out just pretend that they're tables. I've never tried anything like this before, though, and I'm not entirely sure how to proceed.
How can I use Entity Framework to map my classes to these views? Note that it kinda needs to be my POCO classes, rather than anything EF auto-generates - is there a way to tell EF to map existing classes?
If you use code first then Entity Framework will generate CreateTable instructions in the migrations. To use a view instead, replace this code with your own Sql to generate the View. See the answer to this question: Mapping Database Views to EF 5.0 Code First w/Migrations
I would also configure Entity Framework to use stored procedures. Then you can tailor the insert/update/delete sql to match the underlying tables. Again, you can do this by altering the sql that is generated for you in the migrations.

EF Migrations - straight to final schema

My schema has evolved over many iterations. I have a set of migrations taking the schema from an empty db to one with dozens of tables and scores of columns.
Along the way there have been several additions of tables, columns and constraints, sometimes followed (in light of experience or new knowledge or changes in the spec) by removal or alterations. Sometimes a table or column name has been re-used or re-purposed.
Now, EF migrations seems perfectly able to run through the sequence creating, altering, dropping, creating again, altering, etc., to get to the latest schema, but it feels wrong. In an extreme case there might be dozens of migrations creating tables followed by dozens more dropping tables until the final schema might be one or two tables (unlikely, I know). An option to go from scratch to just those final tables would feel right.
In my Ruby days with ActiveRecord migrations there was an option to build only the final schema, without stepping through and possibly undoing or redoing work along the way. Of course this meant keeping a complete DDL version of the schema up to date after each migration, but somehow it felt more elegant.
Has anyone done anything similar with Entity Framework?
You might like to try deleting the __MigrationHistory table from your database, removing the Migrations folder (backing up your Configuration.cs file), and then enabling migrations again.
Then start here for PM commands to build scripts
Generate full SQL script from EF 5 Code First Migrations
from code, there is an option on the ObjectContext not directly on DbContext
string script = (context as IObjectContextAdapter).ObjectContext.CreateDatabaseScript();
Of course Automated Migrations would work if you dont need to see the magic and have altered the generated scripts.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourDbContext,
YourMigrationConfiguration>()
Context.Database.Initialize(true);
And if it is an EmptyDb Schema, EF will do that for free.
Context.Database.Initialize(true);

Entity Framework Self Tracking Entities - Synchronize between 2 databases

I am using Self Tracking Entities with the Entity Framework 4. I have 2 databases, with the exact same schema. However, tables in one database will be added to/edited etc (and I mean data will be added/edited, not the actual table definitions) and at certain points of the day I will need to synchronize all the changes between this database and the other database.
I can create a separate context for both of them. But if I read a large graph from one database, how can I update the other database with the graph? Is there an easy way?
My database model is large and complex and fully relational. So it would be a big job to go through every single entity and do a read from the other database to see if it exists or not, update/insert it if need be, and then carry this on through the full object graph!
Any ideas?
This is not a use case for EF. In EF you will have to do exactly what you've described. Self tracking entities are able to track changes to these object instances - they know nothing about changes made to their own database over time and they will not know anything about state of your second database as well.
Try to look at SQL server native features (including mirroring, transaction log shipping or SSIS) and MS Sync framework. Depending on your detailed requirements these tools can suite you better.

What are the differences in EF when using your own Insert, Update and Delete Functions?

I am looking into adding history tables to my database. The easiest way is to intercept all Insert, Update and Delete calls that EF Makes and add in a merge that will also insert a history row into a history table.
Right now all my Entities just let EF figure out how to do the inserts, updates and deletes.
If I go and add in stored procedures (instead of the EF Generated stuff) will EF still function the same on the business tier?
Or does it change how I have to work with my entities? If so, how?
Everything works the same, it is transparent.
Stored procedures need to return the rows affected, in order for EF to know that the update succeeded or not. Additionally, if you do an update and need to map any property back to your entity (e.g. timestamps) you must select them in the sproc and then map them back in the EF designer (since you can only have one output parameter, and that should be the rows affected).
You might consider using triggers on the DB to solve your issue, though?
Doing this in stored procedures means that you will write all inserts, updates and deletes yourselves. It is like throwing 30% of feature set (and 50% productivity) away. Create audit records in your application and save them together with main records through EF.