EF 4.1 DbContext Generattor - Put Entities in different project? - c#

As a part of our application architecture, we like to define clear lines between our functional layers. A typical application solution, therefore, will contain:
Entity
Model
Task
Presenter
FrontEnd
These end up being completely distinct assemblies.
The Entity/Model delineation is done to keep database access functionality in a separate layer from our POCOs, so that only Task ever need know about Model, while everyone up to Presenter knows about Entity
This works well when using Code-First or Fluent-API - but due to the lack of support for SPROCs in those paradigms, it turns out that under EF 4.1 I must use EDMX models.
So - I'm generating POCOs using a DbContext Generator, but the resulting classes end up under .Model, and while I can force their namespace into .Entity instead, they still live in the .Model assembly, which means now .Presenter must reference .Model to get to classes that should be in .Entity.
Is there a way to force or trick EF to dump its generated output into a different Project?

Sure. DbContext Generator are just two T4 templates. You can move the template generating entities to other project. You just need to modify template to point to correct EDMX file. This is default:
string inputFile = #"Model.edmx";
You must change it to relative address to your EDMX file. It will be something like:
string inputFile = #"../Model/Model.edmx"
The template will automatically use default namespace of current project for generated entities but you will have to modify the second template for context to use the new namespace so that entity types are correctly resolved from referenced assembly.
There is small disadvantage of using template in another project - it will not update automatically when you modify model. You must always trigger entity recreation manually by using Run custom tool from context menu on template file.

Related

EF Core : how to re-scaffold without losing custom changes?

There is a WPF application that is currently transitioning from Entity Framework 6 to Entity Framework Core 5 (database provider is Oracle, the application uses .NET 5 so EF Core 6 isn't possible currently).
There is one big issue to solve: two scaffolded data types weren't correct (from bool to byte and from bool to int). I changed those types manually. If I now re-scaffold, those changes will be removed for sure.
So my question: is there any possibility to re-scaffold (using the -force parameter) without losing the manually changed types OR is there any possibility to override the types which will be generated by scaffolding?
In Entity Framework 6, we used custom data type on EDMX creation to solve this issue:
What I tried and missed: creating a partial class with the same class name (but different file name) which only contained my changes.
The reason why I'm not using migrations is that I use different database stages.
Thanks for your help!
What I tried and missed: creating a partial class with the same class name (but different file name) which only contained my changes.
This will work with the caveat that when the db is re-scaffed the new entities will have the same props appear again (but wrongly typed) and if they're also defined in your partial class you'll get a compile error due to two members having the same name
I'd recommend you install EFCore Power Tools extension and use it to scaff (Reverse Engineer) because there's a section of the "wizard" where it asks you which things you want to scaff and you can untick those columns in the DB to omit them from the models. If they take part in some relationship or have atypical properties meaning they get special attention in the fluent config then you might have to consider an alternative strategy that I use a lot; scaff to a different folder and then run a diff tool to help you merge changes into the main model, then delete the new scaff set.
I leave myself comments in the context that "is the main one", such as "//do not remove this enum column config during context merge", having set up some fluent blah that I know will not be present in the new scaffing
EFCPT does also have some abilities to customize the generated code but I don't know if it goes as far as entirely rewriting parts (I've never looked). It's open source so you can also look at modifying it to meet your needs

How to dynamically create db tables with code first in a prism wpf modular app?

I'm using prism to build a modular app with pluggable modules.
I've already set up sqlite with EF successfully in a separate project to be included in each module.
BUT
I want my module to have a "Model" folder with classes required only by it, in a way that, when loaded by the wpf shell, the system will create db tables for it (if they already don't exist).
How can I "inject" my model classes into the DbContext class at runtime like when I register views and viewmodels with UnityContainer?
T4 (Text Template Transformation Toolkit) is a tool which you can use it to generate DbContext automatically from your Model classes.
I will not write the whole code example because we have already a good example in the given link below:
https://www.paragon-inc.com/resources/blogs-posts/using-t4-to-generate-a-dbcontext-in-code-first
How can I "inject" my model classes into the DbContext class at
runtime like when I register views and viewmodels with UnityContainer?
T4 idea here is similar, you generate your DbContext with all DbSets from the existing classes(Model):
This apporach will extend the DbConext and adding the "Model" folder with classes dynamically(Reflection) in Complie Time.
1) With T4 generate your DbContext class
2) With reflection load your Model entities (retrieve the model class names which you can use them to create the DbSets in the step 3)
3) With T4 generate the DbSets from the loaded entities(step 2) and adding them to the DbContext
[Optionally]
If you want to generete the entities and the DbContext with T4 then, you can take a look to this project.
https://github.com/coni2k/DbContextGeneratorWithCodeFirst
if you use EF 6 you can try modelBuilder.RegisterEntityType(type); for adding new Entity in you context and you can handel migration configuration to add your entity. Also you can use modelBuilder.Configurations.AddFromAssembly(assembly); to add your Entity configuration to your context.
i have a modular web application in this way.
when my web application is started i check all modules and added the entities and shared entity to a context (BTW. some of modules have there own context) and migration do our changes to main database.

How to generate Entity Framework 6.x POCO classes with mappings from an EDMX file?

I'm in the process of converting an extensive EDMX model into POCO classes. I need to go from a Database First approach (EDMX with ObjectContext) to a pure Model First approach (DbContext with no EDMX file). I need to use the latest Entity Framework stable version: 6.1.1.
I've tested some approaches:
Adding a the EF 6.x DbContext Generator code generation item by right-clicking the blank space in EDMX designer. This works fine, but it doesn't add any mappings. With this approach I have to still use the EDMX file. It's not full Code First.
Using the EF 5.x DbContext Fluent Generator for C#. This triggers an exception in design time. I'm not being able to use it. I don't know if that's because my VS Entity Framework tools are already updated to 6.x. Using the alternative TT in the comments, that suggests that it would work with EF 6.0 also doesn't help.
Using the EntityFramework Reverse POCO Generator. This is the worst because it won't consider any of my classes and navigation properties renames.
Using the Entity Framework Power Tools Beta 4. Again, it only supports generating from the database, not from the EDMX file.
My requirements:
I need the input to be the EDMX file, not the database.
I need the output to be a full Code First approach with Fluent mappings.
I need all my navigation property names defined in the EDMX to be considered because otherwise it would break a large codebase, even more then migrating from ObjectContext to DbContext will break.
What do you think would be a good option for me to go?
Well i don't think there is an easy one click solution to this.
Underneath you edmx files. You have two more files available besides the xx.Designer.cs and xx.edmx.diagram.. called xx.Context.tt and xx.tt where xx is the name of your edmx model.
These are t4 templates which genrate your dbcontext and poco objects. All your poco objects would be created underneath your xx.tt files and dbcontext underneath your xx.Context.tt files.
You now have to moves these into separate files. This is much easier if you are using EF6. and the file generated are already using DbContext and not ObjectContext.
I faced a similar case and I used Entities to DTO's generator.
Although its purpose is to generate DTO's, however, I believe it can help someone in you case.
https://entitiestodtos.codeplex.com/

How do you modify your database after generating your DbContext?

Now that i have generated 19 code-first classes from an existing database by:
Creating a Model-First Entity, and choosing "Generate from database"
Right clicking and choosing "Add Code Generation Item"
EF 4.x DbContext Generater
All the classes i want are generated, and I'm very happy with them...
And now for my question(s)
Why are they all the generated .cs files nested in a sealed .tt collection?
Why can't i copy paste them out to any folder i like, and treat them like normal classes?
Is it just me, or are you unable to use migrations "update-database" when you do it like that?
I guess my overall question is, why are they located in a .tt folder?
And how shall i update my database now? By editing the database manually and then update the Model, and then generate the dbContext again? Or is there a trick to get .cs files out of a .tt folder?
How do you modify you database after generating your DbContext?
Why are they all the generated .cs files nested in a sealed .tt collection?
Your code-first classes are not code-first classes. They were generated based on your database schema. Hence, this is a database-first approach. With database first, your entity classes are generated based on the database. In other words, the database comes first, the code comes second. The .tt file is a T4 template that decides how to generate your classes based on the database. You could change the database and then regenerate your entity classes.
Why can't i copy paste them out to any folder i like, and treat them like normal classes?
Because they are generated files, based on the T4 template.
Is it just me, or are you unable to use migrations "update-database" when you do it like that?
This part of your question I can't answer for certain, and will have to defer. However it seems to me like you want to mix and match approaches. It sounds like you want to start by generating code classes based on your database, and from there forward, change the database based on new entity classes you add to the model project. Is that right?
You can forgo the code-generation part and just go with a pure code-first approach, now that you have an idea of what the entity POCO's should look like. I have tried this T4 code generation before (pre EF 4.1) and immediately abandoned it, because as you have seen, since the entity and DbContext classes are generated, you lose control over the object-oriented model.

Change EF Entity naming pattern when generating model from database

Is there a way to change the pattern that EF uses to generate the Entity name when generating the EDM model from an existing database?
Example:
I have a table: table_name and I want my entity to be named TableName without me having to change it manually.
EDIT: I know I can change the POCO generation template, but how about the EDM generation? Is this done with a template as well? If so, where is this template located?
I'm affraid it is not possible - at least not without investigating possibilities of EF Designer extensibility or investigating EdmGen internals. The point of Entity designer is to allow you easily map / change those names.
Interestingly it is possible if you start with model (EF designer) and want to generate database from the model - in such case the process is controlled by workflow and T4 templates and you can change it but in case of generating model from database the process is most probably hardcoded inside Edmgen tool - you can check if this tool has any API which would allow you changing the behavior.
Anyway EDMX is just XML so if you have exact pattern you need to replace you can create very simple tool, transformation or script which will modify your EDMX file after generation from the database.
You cannot change the POCO T4 template. The template must produce classes with exactly same names as you have for entities in your model. Otherwise the POCO magic will not work.

Categories

Resources