How to avoid program exception when ef model changes? - c#

I use a third party database with Entity Framework 6. This works fine; however, when a table within my model is changed (three columns were deleted), my program throws an exception:
System.Data.SqlClient.SqlException: Invalid column name '<deleted column>'
I don't use any of these columns. I only read them from the database.
I can update my model, but then when there is another change in a table, my program will crash again. How can I modify my program so that it won't crash on the next database change?

You can use a Code First approach starting from database (generate classes from database). At the end of class generation you can delete entities that you don't need (i.e. entities related to all unused tables) or properties related to unused fields.
Disable migrations.
You can also delete intermediate files generated by EF code generation (files different from .cs files).
At this point, any changes to database that not affects mapped classes/properties does not cause errors in EF.

Create a context with only the entities you need. Create entities with only the properties you need.
see EF code first.
Use Fluent API to specify primary keys and more.
It will still crash though if any of your entities/properties gets changed/deleted

Related

EF code first created a column on DB table that does not exist in my model

I didn't find any question here that addresses this problem specifically, so here it goes.
I'm using EF Core Code First. One of the tables generated by EF migrations has an additional column that does not exist in my model. It might have existed, as I can see in the ModelSnapshot file, but it was removed a long time ago.
This entity does not have any complex object apart from the identity user and all other properties are primitive. (strings, ints, etc)
I have already tried to add that same field and generated a migration and it appears empty.
Then I tried to remove the field from the model and generated the migration again to see if now it recognizes I am removing it, but again.. migration empty.
I am thinking of removing it from the DB manually but the problem is that it still exists in the model snapshot file, which can generate other sync issues.
I would appreciate any ideas on how to solve this. Thank you very much.

How to remove the tables and migration records for an EF6 DbContext?

I am writing a service that will decide at some point it needs to store values and so needs to create tables inside an existing database. Later on, it will decide it no longer needs this storage and so should remove those tables. This cycle could repeat multiple times. I am using EF6 to simplify the database operations.
Creating the tables is easy as the first time the DbContext is used it will automatically create the tables along with the initial migration record. To avoid having to create verbose migration classes I just derive from a class from DbMigrationsConfiguration and then set the AutomaticMigrationsEnabled to true. Then it generates the tables using the code first model classes.
The problem is that later on I need to remove these tables and the matching migration record. There does not seem to be any useful method for doing that. The closest I found was DbContext.Database.Delete(). This is not appropriate because it attempts to delete the entire database and this is not possible because the database has lots of other tables used for other purposes.
Is there no way to tell EF6 to remove all the tables and migration record for a DbContext? That seems a strange omission. I do not want lots of zombie tables lingering that are no longer needed. Not everyone can create and delete an entire database to support a single DbContext.

How to make Entity Framework DB-first generate single .cs file instead of one file per class

I've an existing database with many (~500) tables and stored procedures. Whenever the database gets updated, I need to re-generate the .edmx file for Entity Framework 6 based on the new schema; the process produces about 500 files, one per each table and at least one per each stored procedure that returns results.
For various reasons, I'd rather have a single file with all classes in it.
I know I can comment out this line <EntityModelName>.tt to consolidate all files:
// fileManager.Process()
However I can do this only after Entity Framework generated 500+ files. Having to do this every few days gets quite annoying.
Updating the .edmx file instead of deleting and re-generating it often results in errors due to DB schema issues that won't be resolved anytime soon.
What would be the best way ensure that only one .cs file generated from the outset? I am willing to go as far as forking EntityFramework, modifying VS templates, or doing other unconventional things as necessary.
You can use this tool which you can configure to generate all your POCOs into a single file (by default) or to separate files, also it has more options can you look at and check through the video exists on the link that I've mentioned.
Remember that you can switch between code-first and database first by just setting the context's initializer to null, so something like :
public class MyDbContext : DbContext
{
static MyDbContext()
{
// I don't want to initialize my database from code, I already have a database.
Database.SetInitializer<MyDbContext>(null);
}
//
//
// you dbsets goes here
}
You can find more details about initialize db contexts here.
So in a few words you can use the tool to generate the POCOs for you and still use your database, which is much cleaner than using EDMX files.
Let me know if you need more details or if you still confused.

Does an DB-First Entity context have to match the database schema, even for unused tables?

I have an application that uses EF 5 and a database-first context which maps all the tables in a SQL Server 2008 database. Some of those tables are not used by my application. If I change the structure of an unused table, will it break my existing EF code?
I will update the .edmx to match the changed table soon (and yes I'll look into a bounded context too). I'm just curious to know if I need to do so, even when the table is entirely unused by my application.
If you attempt to access the mismatched tables either by accessing it's DbSet<T> query or by access a navigation property to a T or ICollection<T> you will get a runtime exception. It will be some type of System.Data.EntityException (probably a System.Data.MappingException). The same thing will happen if you attempt to access a table that no longer exists.
It should not cause any exceptions until you access the mismatched/missing table.

View using same type as Table

I have a table that used throughout an app by Entity. I have a view that returns an identical column set, but is actually a union on itself to try to work around some bad normalization (The app is large and partially out of my hands, this part is unavoidable).
Is it possible to have Entity 4 treat a view that is exactly like a table as the same type, so that I can use this view to populate a collection of the same type? This question seems to indicate it is possible in nhibernatem but I can't find anything like it for entity. It would be an extra bonus of the navigation properties could still be used to Include(), but this is not necessary (I can always manually join).
Since EF works on mappings from objects to database entities this is not directly possible. What you need is something like changing the queried database entity dynamically, and AFAIK this is not possible without manually changing the object context.
For sure the EF runtime won't care as long as it can treat the view as if it was completely separate table. The two possible challenges that I forsee are:
Tooling: Our wizard does allow you to select views when doing reverse engineering (i.e. database-first). Definitively if you can use 'code first against an existing database' you can just pretend that the view is just a table, but you won't get any help scripting the database creation or migrations.
Updates: in general you can perform updates for a view setting up store procedure mapping (which is available in the EF Designer from v1 or in Code First starting in EF6). You might also be able to make your view updatable directly or using instead off triggers (see "Updatable Views" here for more details). If I remember correctly the SQL generated by EF to retrieve database generated values (e.g. for identity columns) is not compatible in some cases with instead-off triggers. Yet another alternative is to have your application treat the view as read-only and perform all updates through the actual table, which you would map as a separate entity. Keep in in mind that in-memory entities for the view and the original table will not be kept in sync.
Hope this helps!

Categories

Resources