Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine Code First & Database First In Single Model?

Is there a way to combine code-first and database-first in the same context? We are running into massive development-time performance problems when editing the EDMX file (it takes 1.5 minutes to save). I've moved our non-insert/update/delete UDFs/stored procs to some custom T4 templates that automatically generate model-first code, but I can't seem to get OnModelCreating to be called when EDMX is involved.

Other things we've considered, but won't work for one reason or another:

  1. We can't (reasonably) separate our code to multiple contexts as there is a lot of overlap in our entity relationships. It also seems like quite a people who have gone this route regret it.

  2. We tried having 2 different contexts, but there are quite a few joins between Entities & UDFs. This may be our last hope, but I'd REALLY like to avoid it.

  3. We can't switch to Dapper since we have unfortunately made heavy use of IQueryable.

  4. We tried to go completely to Code-First, but there are features that we are using in EDMX that aren't supported (mostly related to insert/update/delete stored procedure mapping).

like image 454
randomsolutions Avatar asked Nov 09 '16 17:11

randomsolutions


People also ask

What is the code first approach?

In the ASP.NET MVC framework, the code-first approach is a development model where you first write the code that creates the data access layer, then you write the code that creates the controllers and views. In the code-first approach, you create a model, which is a class that represents the data in the application.

Can we use code first with existing database?

To use code-first for an existing database, right click on your project in Visual Studio -> Add -> New Item.. Select ADO.NET Entity Data Model in the Add New Item dialog box and specify the model name (this will be a context class name) and click on Add. This will open the Entity Data Model wizard as shown below.

Which is better code first or DB first?

Versioning databases is hard, but with code first and code first migrations, it's much more effective. Because your database schema is fully based on your code models, by version controlling your source code you're helping to version your database.

How do I convert code first to database first?

There is no way to convert your code-first classes into database-first classes. Creating the model from the database will create a whole new set of classes, regardless of the presence of your code-first classes. However, you might not want to delete your code-first classes right away.


2 Answers

Take a look at the following link. I answered another question in a similar fashion:
How to use Repository pattern using Database first approach in entity framework

As I mentioned in that post, I would personally try to switch to a Code First approach and get rid of the EDMX files as it is already deprecated and most importantly, the maintenance effort is considerable and much more complex compared with the Code First approach.

It is not that hard switching to Code First from a Model First approach. Some steps and images down below:

  1. Display all files at the project level and expand the EDMX file. You will notice that the EDMX file has a .TT file which will have several files nested, the Model Context and POCO clases between them as .cs or .vb classes (depending on the language you are using). See image down below:
    enter image description here
  2. Unload the project, right click and then edit.
  3. See the image below, notice the dependencies between the context and the TT file
    enter image description here
  4. Remove the dependencies, the xml element should look like the image below:
    enter image description here
  5. Repeat the procedure for the Model classes (The ones with the model definition)
  6. Reload your project, remove the EDMX file(s)
  7. You will probably need to do some tweeks and update names/references.

I did this a few times in the past and it worked flawlessly on production. You can also look for tools that do this conversion for you.

This might be a good opportunity for you to rethink the architecture as well.

BTW: Bullet point 4 shouldn't be a show stopper for you. You can map/use Stored Procedures via EF. Look at the following link:
How to call Stored Procedure in Entity Framework 6 (Code-First)?

like image 99
Charles Avatar answered Oct 06 '22 20:10

Charles


It also seems like quite a people who have gone this route [multiple contexts] regret it.

I'm not one of them.

Your core problem is a context that gets too large. So break it up. I know that inevitably there will be entities that should be shared among several contexts, which may give rise to duplicate class names. An easy way to solve this is to rename the classes into their context-specific names.

For example, I have an ApplicationUser table (who hasn't) that maps to a class with the same name in the main context, but to a class AuthorizationUser in my AuthorizationContext, or ReportingUser in a ReportingContext. This isn't a problem at all. Most use cases revolve around one context type anyway, so it's impossible to get confused.

I even have specialized contexts that work on the same data as other contexts, but in a more economical way. For example, a context that doesn't map to calculated columns in the database, so there are no reads after inserts and updates (apart from identity values).

So I'd recommend to go for it, because ...

Is there a way to combine code-first and database-first in the same context?

No, there isn't. Both approaches have different ways of building the DbModel (containing the store model, the class model, and the mappings between both). In a generated DbContext you even see that an UnintentionalCodeFirstException is thrown, to drive home that you're not supposed to use that method.

mostly related to insert/update/delete stored procedure mapping

As said in another answer, mapping CUD actions to stored procedures is supported in EF6 code-first.

like image 23
Gert Arnold Avatar answered Oct 06 '22 20:10

Gert Arnold