I'm starting a new .NET MVC project with Entity Framework and I am struggling with some problems.
In my model I have about 150 entities (generated from the database). Is it a good idea to have only one DbContext? If not, how should I divide my entities?
If I have one DbContext and I create a class variable that instantiates a database context object (in Controller), what happens then with this DbContext? Does it create in memory separate space for each of my entities? In my case, when I have 150 entities it would not be very effective. Am I wrong?
I will be using my DbContext in many Controllers. Is it a good idea to create a MainController (where I create new DbContext), which will be inherited by the rest of the Controllers? Because this allows others to have access to the same Context.
What is the best practise for disposing my DbContext? I've read that it is good practice to use dependency injection. But in this way I will have to inject context to every of my controllers. Which dependency injection way is the most popular and used now?
Really need your advice. It will give me more insight to this piece of development.
It is fine to have one DbContext. If you have many you just need to ensure all the entities you need exist in the that context. For example, if you retrieve a Person from the database and their related Address, then both the Person and Address have to exist in the same DbContext.
I've not tried using multiple DbContext instances, but one thing to look out for is if you include the same table in multiple contexts you could end up with classes with similar names or maybe conflicts. For example, if you include Person in two contexts, then each context will attempt to create a class named Person.
When you create a DbContext it will only create objects for the data you retrieve from the database. So if you request one row from a Person table, then only one Person object will be created. If you request 100 rows, then 100 instances will be created.
There are really two options. One, create a new instance in each action, do your work, then save it. Or, create a DbContext in your constructor and reuse that throughout the class.
This depends one what you choose in point #3. If you pass it into the constructor, then implement IDisposable and release it in there. If you create a new one in each action, then ensure it gets disposed using the using statement.
For dependency injection there are a number of options, tutorials, etc, on how to do this in ASP.NET MVC. I personally use Autofac, and related MVC extensions, and pass a new instance of the DbContext into each controller.
150 Entities is not a huge DbContext, but it is above the size where EF starts to exhibit performance issues in the initialization of the first DbContext. If you can logically separate your entities into areas of responsibility (called a bounded context) then you might consider using more than one DbContext. Also, does your app need to use all those entities? If not, you may be able to simplify things. Also note, you need at least EF6 to make this work effectively, previous versions of Entity Framework had issues with multiple contexts.
You also have to be careful when using multiple contexts. Many people get into trouble because they get an entity from one context, but then call save changes on a different one, and then don't understand why their changes are not saved. Or, they try to add an entity retrieved from one to another, which you can't do. Multiple contexts make things more complicated, so make sure you want to take on that complexity before you split it up.
Don't worry about the amount of memory your DbContext uses, so long as you are properly disposing of it. The amount of memory will be minimal unless you actually load objects from all of those tables.
I consider a common base controller to be a code smell. It's usually completely unnecessary, and it usually ends up becoming a dumping ground for every piece of code you think you want to share, which violates the Single Responsibility Principal. On top of that, you shouldn't be doing data access in your controllers anyways. You should have a service layer of some sort or business layer that call into a data access layer. Properly segregating your concerns is a key part of designing a good MVC application.
Yes, Dependency Injection is a good practice. I'm not sure what you mean by "have to inject into all my controllers". The whole point of dependency injection is to inject your dependencies, so the concept of "having to" makes it seem like you're trying to avoid the very thing you're trying to do.
Dependency Injection is a principle. There are many ways to achieve this principle, and which way you use depends entirely on your own preferences and requirements. We can't tell you what's "best" other than to make sure you're following the principle, and not a specific technology.
Regarding the dbcontext question:
I would go with multiple dbcontext (bounded contexts).
One problem with single big dbcontext is the loading and the Initializing time as it will map all the entities and this increases when your entities number increase in your context.
Now your project must consist of modules and this where you can divide your big dbcontext into small db contexts that covers all what each individual module needs to work with the database, for example let's say that your project has two modules (membership and billing or financial) for customer/person entity, you will find that when you deal with person in the membership module you need all his details but not full details of his invoices, and when you deal with the person in the billing module you will need all his invoices deatils but not his full personal information, here you can create 2 dbcontexts one for each module with person entity contains what that module needs from the person entity.
Julie lerman has a good article about dbcontext with Entity-framework that start with to get more details about what I am trying to describe here,
https://msdn.microsoft.com/en-us/magazine/jj883952.aspx
Hope this helps
I am working on a project that has a static library shippable. The static library uses core data and I succeeded to compile my core data model into a separate bundle and ship the bundle with the library as it is described for example here: core data in a static library for the iPhone.
Now my problem is that I would like to make the core data entities in the data model of the library inheritable. Thus the user could extend these entities, adding his own attributes and relationships to my base entities via core data inheritance. How could I achieve this considering that due version control purposes or package managers (I use cocoapods for the static library) it is better not to let the user modify the original core data model?
My current solution is to ship the original data model as a "template" and ask the users of the library to create a copy of it, extend it, and include only the extended data model and not the original one. But this feels somehow unprofessional and creates a mess for the users. Are there any other solutions that I am not aware of?
I am using CoreData in my iOS application. I face a problem most of the times while creating NSManagedObject classes.
This is what I do:
I create an Entity in .xcdatamodeld file.
Create attributes and relationships.
Choose option Editor->Create NSManagedObject Class to create .h and .m classes.
In .h and .m classes, I create some of my custom methods for fetching/saving objects.
So far so good. But afterwards in future if I have to change some attributes, I repeat step 2 and 3. But this time all of my custom code written in step 4 are removed automatically.
So my question is how can I update the existing classes? Instead of using option Editor->Create NSManagedObject Class which removes all my custom code.
Any help is appreciated.
Update:
Tested both approaches (Categories and Mogernator) and looks fine to me. But I have choosen Categories of being a pure Xcode approach. I don't want to take the risk of any 3rd party which may break in future due to XCode updates or can cause problem of data migration.
Thanks to #Tom Harrington, and #Valentin Shamardin for guiding me :)
To make some additional methods or other stuff for your Core Data model classes you have to create Categories. This approach is used by Paul Hegarty in Core Data lections.
The best way to handle this is to use mogenerator to generate your model classes instead of having Xcode do it. With mogenerator you get two classes for each entity:
One that is re-generated every time you rebuild the model classes
One that is a subclass of the other, which is only generated the first time you build model classes and which mogenerator never changes afterward.
As a result you can put all your custom code in the subclass, and no matter how many times you re-generate your model classes, your code is never overwritten.
Whenever yo change or update your core data object model it becomes incompatible and cannot be open and as a result it gives crashes.
For this you need to perform Core Data Model Versioning and Data Migration.
Versioning is nothing just only provides you which model version is application going to use. Changes and update in core data model like modifying any attribute of entity or adding new entity. It is related with Core database model. Consider your application going to use 1.0 ver and using database model of 1. if u have some changes in database model its version increases and now you application going to use next version ie 2 of core database model
The details refer to this Apple Doc for Core Data Versioning
Also this will result in old Data loss. For this you need to perform Migration Process.
During migration, Core Data creates two stacks, one for the source store and one for the destination store. Core Data then fetches objects from the source stack and inserts the appropriate corresponding objects into the destination stack".
Please refer to Migration Process details on Migration on Raywenderlich
You need to use NSMigrationManager class and
I am developing an iOS app and have several object models. Now I want to convert them to core data managed objects, so creating the entities and attributes from the object instead of the standard opposite way of generating the objects from the model. What is the best way to accomplish this?
I tried extending from NSManagedObject instead of NSObject, then manually creating the entities and attributes and setting up the Class name for the entity but that didn't work :-(
Thanks
I recently did this for a big project with a very large and complex data model. Here is a workflow that I found to be very feasible.
First, I create a new data model in Xcode and populate it by hand. This is a very good exercise as it forces you to review your model and perhaps take advantage of simplification opportunities.
Then, generate your class files with Xcode from the model. If you have any special code that should be included in the objects, add them as categories in separate files (e.g. Event.h & Event.m generated by Xcode, Event+Additions.h & Event+Additions.m with your code).
I have two .edmx files each containing different entities, using the same database.
On file one i have my app logic entities, one of them is a table called Report.
On the other file i have infrastructure entities such as User table and some authentication stuff.
I want to add a Navigation property from Report on file one to use User on the other file. Is it possible ? I am used to just drawing an association with the toolbox but I don't see how i can stretch the line from one designer to the other.
It is not possible. You must map User entity again in the EDMX with Report entity but in such case you must be very careful with code generation. If both your EDMX produce entities in the same namespace or if you are using POCOs you must avoid User entity to generate class again - it means modifying code generation template.
EDMX has some limited support for reusing types but it is possible only on conceptual level (database level and mapping level must be shared) and because of that it is possible only if you don't use EF designer and maintain EDMX manually as XML.