Reuse code first model between different clients - entity-framework

I have a code first model that I'm using in a project. But now I have other projects that are going to use the same model. Of course, I don't want to duplicate the model in all projects so the idea is to encapsulate the model in a separate assembly. So far so good, until you also want to "enhance " the model for some project like adding a ctor with some specific paramaters.
Using partial classes doesn't work as it needs to be part of the same assembly. Using inheritance doesn't really work either as entities of the model has ICollection to other entities, so how to make this work ? Am i going in the right direction ?
Not sure I'm very clear, so please be patient ;-)

If you need to have shared model, you really need to place it in separate assembly and this assembly must contain everything you need in all projects. So if you need additional constructor you must add that constructor to the shared assembly. If you don't want to affect other projects dependent on that assembly you must increment the version of the shared assembly (and use strong name).

Related

Trying out Entity Framework Code-first; is the usage any different from Database-first?

When working with EF (v4,5,6) I have always used Database-first (I was mistakenly under the impression this was the only way to generate Entities from existing tables, EDMX, etc). But today I tryed Code-first, and it can also generate the POCOs (in a different way, no EDMX, different connection string, less cr8p lying around, etc..!)
So far, the usage of EF for CRUD appears to be exactly the same, can anyone who has used both please confirm there is nothing different (in usage), or gotchas I should be aware of?
And a supplementary question is, can I generate both in the same project ? (Not that i want to, but existing proj has EDMX within a folder, can I create another folder and generate Code-First Entities (different set of tables only), so i end up with DBContext and DBContext2 ?
Yes, the usage is the same. If you check the generated code you'll see they use the same System.Data.Entity.DbSet properties and they both inherit from the same System.Data.Entity.DbContext class.
Yes, you can generate both in the same project, but does not makes much sense, because you have to maintain both of them if the DB changes.

Reference existing CF project models

We have multiple model projects using codefluent (M1 and M2).
Is it possible to have one model project (say M1) using type reference of another model project (M2) ?
I tried adding project reference or existing item in model but none of them worked.
The import feature doesn't seem to be the way to go either
Shall I consider having only one model project for my solution ?
Thanks for your answer,
I think you want to create a relationship between entities of both models.
If so, it's easier to have only one model. If you create multiple models because of their sizes, you may be interested in parts and surfaces to split it (blog post about surfaces).
If you want to have multiple models, I think it's possible to create relationships between entities (but I didn't test it). You need to create the entity in both model and play with the producer specific attribute enabled (cfps:enabled, cfom:enabled, etc.). Unless you really want to do complex things, I think you may stick to one model.

Prevent compiler to stop undo my changes in T4 classes Entity Framework

I am using Entity Framework and want to do some changes in context class
For ex. I am creating one more constructor for connection string but issue is every time when I open .edmx file and save it, then my changes are no longer exist.
Is there any way for me to tell .edmx not to undo my changes in context class or T4 classes?
You cannot change the generated code. You can add things to it since the classes that are generated are partial classes.
Add your additions to a separate file containing the custom part of the partial class.
See here: https://msdn.microsoft.com/en-us/library/wa80x488.aspx
An alternative is to modify the T4 template yourself and consistently apply your specific needs to the generated classes.
It is common practice to do this when for example you want INotifyPropertyChanged as interface on every class.
This approach only works if your changes are generic in nature. If you want to do a specific change in only one class then this solution does not work for you.
Another alternative is to take full control of the classes by using code first.
You can mark the methods and properties with special attributes to map them to the db. And there is a reverse engineering option to create these classes from an existing db. You would reverse engineer once, and then take control of the classes and tweak them to your needs
I generally take the last approach myself right now, because it is not using partial classes all code that belongs to a class is all in the same file.
The answer of Maarten is also fine, but there are 2 more options.

I have three projects that share the same DB, whats the best way to use EF across all?

I have three projects (WCF projects, not clients), I have one database for all, now how will I use EF with this? should I make a fourth project which will have the db context and the entities and then add a reference to it in all three projects? or should I just have a separate context for each project and just add the tables i need for each project? some of the table are really used everywhere. so what's the best solution for this?
Another question: should I expose the EF db context in the separate project so other projects can access it? something like:
MySeparateProject myPr = new MySeparateProject();
using (var db = new myPr.DBContext())
{
// do stuff with entities
db.SaveChanges();
}
I think the cleanest thing to do is create a data access project (class library) that contains just your models and db context, and reference that from all of your other projects.
Some people will say that you should make one class library with just the models, and then have yet another that has the DbContext, and the have repository classes, and then.... I feel this is overkill for the majority of projects. Having the models and context in one place just makes it really easy to keep all the dependent projects consistently in sync when it comes to data access.
Here's a typical project structure for me:
Here, Squelch.Data contains all of my models and db contexts, Squelch.Core contains core business logic, and my two "applications" (Squelch.Portal ad CdrImport), and the various test cases, all reference these base class libraries.
I would create a separate data access project. It is good practice to separate your data layer out anyhow. Depending on the nature of the project and how you want to test it, you may want to take a look at something like the repository pattern (though there is debate about its value with EF).
http://msdn.microsoft.com/en-us/library/ff649690.aspx

Change MyEntityFrameworkModel.edmx.cs File

I was wondering if can change the edmx.cs file (change inheritance and base constructors of object context derived class).
when I try this , all changes will defect as i build the project.
Note I mean changing the object context derived class not entity classes.
thank you.
If you can afford it (meaning if your project is not too complex already), I could suggest that you switch to code-first style (EF 4.1). That allows you to build all the inheritance you want in your objects. And since you create your own context by inheriting DbContext, you also have total flexibility there.
You can use your EDMX (with the T4 template packed in EF 4.1) or your existing database to create the classes (so at least what you have done until today still stands).
http://thedatafarm.com/blog/data-access/quick-look-at-reverse-engineer-db-into-code-first-classes/
http://devlinliles.com/post/Reverse-Engineer-Code-Firste28093Jump-start-for-existing-Databases.aspx
The partial class solution would maybe do it too (depending on what you wish to achieve).
To change in entity frame work class its better to create Shared classes with same name and add your own methods and properties