227 subtypes of Mapped class causes slow Entity framework database context initialisation? - asp.net-mvc

I have a class Country, with 227 subtypes (one for each Country).
Legacy restrictions prevent me from easily changing this.
I've double checked that in fact the high number of subtypes is causing EF to have a super slow initialisation, on the first call, the first time the DbContext is accessed it takes about 2 minutes!!
Is there any way I can maintain this high number of subtypes in Entity framework and avoid this slow spin up ??
The hang can occur by doing a simple call to Db.Users.Find(1); (for example)

What's hurting you is the initial View Generation that Entity Framework goes through during a cold query (a query against Entities that don't have Views mapped. These Models are the mapping from Entities to Tables that makes EF so efficient afterward:
The process of computing these views based on the specification of the
mapping is what we call view generation. View generation can either
take place dynamically when a model is loaded, or at build time, by
using "pre-generated views"; the latter are serialized in the form of
Entity SQL statements to a C# or VB file.
Pre-Generated Views are designed with EF tools within VS and built at compile time rather than at run-time.
You can also consider using the Entity Framework Power Tools to
generate views of EDMX and Code First models by right-clicking the
model class file and using the Entity Framework menu to select
“Generate Views”. The Entity Framework Power Tools work only on
DbContext-derived contexts and can be found at
http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d.
For more information on how to use pre-generated views on Entity
Framework 6 visit http://msdn.microsoft.com/en-us/data/dn469601.
Check this Reference on Entity Framework View Generation
Everything you need to know about pre-generating views, applying them, and even moving them to their own assembly (so that View Generation builds are independent of Application release builds.

when you create the first instance of Context ,
EF validate DB Schema ,
if the model has no changes , you can skip this step by static constractor :
static ctor
{
Database.SetInitializer<BillingContext>(null);
}

Related

EntityFramework database vs model

I understand the fact that generating a model based on the DataBaseFirst method woill produce a collection of entitites on the ORM that are essentially mapped to the DB tables.
It is my understanding, that if you need properties from other entities or just dropdownlist fields, you can make a ViewModel and use that class as your model.
I have an AppDev course that I just finished and the author wrote something that if I understand it correctly, he is referring to change the ORM entities to fit what your ViewModels would look like, hence, no need for ViewModels. However, if you do this, and regenerate the ORM from the database, those new entities that you placed as "ViewModels" would be gone. If you changed the ORM to update the database, then your database structure in SQL Server would be "undone".
Please inform me if my understanding is correct that I simply need to use a ViewModel in a separate folder to gather specific classes and or properties in a superclass or a single class with the properties that I just need and use that as my model....
Here is the excerpt from the author:
EntityFramework is initially a one to one mapping of classes to tables, but you can create a model that better represents the entities in your application no matter how the data is stored in relational tables.
What I think the author may have been hinting at is the concept of complex models. Let's say, for instance, that in your Database you have a Customer Table and an Address Table. A one to one mapping would create 2 model items, one Customer class and one Address class. Using complex model mapping, you could instead create a single Customer class which contained the columns from both the Customer Table and the Address table. Thus, instead of Customer.Address.Street1 you could refer simply to Customer.Street1. This is only one of many cases where you could represent a conceptual model in code differently than the resulting data in storage. Check out the excellent blog series Inheritance with EF CodeFirst for examples of different mapping strategies, like Table Per Hierarchy (TPH), Table Per Type (TPT), Table Per Concrete Class (TPC). Note that even though these examples are CodeFirst, they still apply to Entity Framework even if the initial models are generated from a Database.
In general, if you use DatabaseFirst and then never modify the resulting entities, you will always have a class in code for each table in the database. However, the power of Enity Framework is that it allows you to more efficiently work with your entities by allowing these hybrid mappings, thus freeing you to think about your code without the extra burden of your classes having to abide by rigid SQL expectations.
Edit
When the Database-First or Model-First entities are generated, they are purposely generated as partial classes. You can create your own partials which extend the classes that are generated from Entity Framework without modifying the existing class files. If the models are re-generated, your partial classes will still be intact. Granted, using partials means that you have the Entity Framework default behaviors as well as your extended behaviors, but this isn't usually a huge issue.
Another option is that you can modify the TT files which Entity Framework uses to generate your models, ensuring that your models are always regenerated in the same state.
Ultimately, the main idea is that just because the default behavior of Entity Framework is to map the database to classes 1:1, there are other options and you are never forced into something that isn't efficient for your project.

Way to customize POCOs and not lose changes with database refreshes

Using EF 4.1 in MVC 3 environment. I'm also using the POCO generation tool I downloaded using NUGET.
I am looking for a way to "customize" the POCO classes with attributes for validation without losing these changes every time the database changes (and a resulting re-sync is performed).
I've tried creating abstract classes and instantiating an inherited class, but EF forces me to create a concrete class through the EDMX file and this descendant class also becomes a generated POCO which is "refreshed" with every database sync.
I've notice the POCO's were partial classes meaning I could add members to the classes in a different file, but this approach wouldn't let me add to existing members.
While I understand that what I'm running into is a limitation of the database first approach, I suspect that there is a way to alter/customize the POCOs in a way that isnt lost with each re-fresh.
You have at least 2 options:
Implement the IValidatableObject interface on your partial class and provide the Validate method.
As Eranga mentions, use the MetadataType attribute to move the validation attributes to another class with the same properties.
Overriding OnModelCreating will only work for code first and isn't an option in model / database first.

Code First and Model First in the same project?

I have two databases that I am accessing. The first is against a contact database which I connected to using EF Model First; creating the edmx. I have since begun to learn the virtue of CODE First when working with Entity Framework, so I decided I would, in the same project, write the Product database using Code First techniques, allowing the database to be generated from the code I am writing.
Everything compiles fine. The problem occurs when I hit my harness and it attempts to create the Product database and retreive a list of values from one of the tables...
I get the folowing error "Could not find the conceptual model type for 'Core.Data.Account'", when I attempt to enumerate the ProductLines property (Line3 below).
1. using (var ctx = new ProductDb())
2. {
3. var lines = ctx.ProductLines.ToList();
4. this.litOne.Text = lines.Count.ToString();
5. }
After some research it appears that this message may be occuring because of multiple entities with the same name (regardless of namespace), however there is nothing in the ProductDb context with the name "Account".
There is a class in the OTHER context created by the Model First approach named "Account". But how/why would that make a difference? They each point to different databases i.e. different connection strings. Why would the ProductDb be attempting to create a table called Account, when it should be completely unaware of it's exstence?
thoughts?
Thank you as always!,
- G
I bumped into the same problem, but the other way around: first a DbContext + generated database and then generated an edmx off the database (just for a little presentation). It appeared to be a restriction in EF: EF currently has a restriction that POCO classes can't be loaded from an assembly that contains classes with the EF attributes.
The only thing you can do for now is keep the contexts in separate assemblies.

Compare Entity Framework 4 objects to ADO.NET C# POCO Entity Generator objects

I really have two questions:
What is the difference between an Entity Framework Entity object and an ADO.NET C# POCO Entity.
Do I have updating a record using a repository correct below?
If you turn off code generation, then add the ADO.NET C# POCO Entity Generator, it provides a nice class representation of your Entity Framework 4 objects. The idea is that (from here):
The POCO Template can be used to generate persistence ignorant entity types
from an Entity Data Model.
However, these objects have the relations between objects as well as a link back to the database. For example, you can pull one out of your repository, alter it, then save changes at the repository or unit of work level, and it saves the content to the database.
So my question is what is different between a native Entity Framework object and these POCOs generated using this tool?
This is what I think when I update a record using a repository. Is this wrong?
Request a POCO from the repository.
The Repository loads the records from the data context, creates a new POCO for each record found, copies the values from the Entity Framework objects to the POCOs, and returns a collection of the new POCOs.
Changes are made to these POCOs outside of the repository, then the POCOs are submitted back to the repository using something like Save(POCO).
The repository loads the matching records from the database and copies the POCO properties to the Entity Framework objects.
One calls Save using either the repository object or unit of work object.
In case of POCO generator the generated entity classes (eg, Employee, Company etc.) don't derive from any special class (hence called Plain Old).
Whereas in case of entityobject generator, the entity classes derive from the special 'EntityObject' class, which provides certain capabilities.
The objective behind having POCO classes is to do away with the DB specific concerns of an entity. Thus keeping our domain model unaware of DB/persistence operations.
POCO means that you have a plain old CLR class which is not polluted by special constructs related to the persistance. Entity objects are derived from EntityObject class and they use a lot of classes and attributes directly related to entity framework. When using EntityObjects you are making your code fully dependent on entity framework.
What you describe in your repository was used in EFv1 to achieve POCO approach. Currently you can use POCOs directly. POCOs don't have any relation to the database. In some scenarios POCOs are dynamically proxied by EF dependent constructs but this happens during runtime so it doesn't pollute your code.

ASP.NET MVC 2 Validation: Metadatatype can't be added to standard POCO CLR classes - what's an alternative?

I am using Entity Framework and generating my POCO classes via T4 - these classes inherit from nothing and are very plain and simple (created via template in vs 2010)
I tried using the Metadatatype Attribute so I could create a buddy class but when I did this I no longer was able to see my properties... if I removed the attribute! the properties appeared.
Anyway, searching deeper I found this statement from Microsoft
The associated class must be used with EDM or LINQ-to-SQL models because CLR types cannot mark existing properties with new attributes. If you are working with CLR objects directly, sometimes referred to as Plain Old CLR Object (POCO) types, you can apply the attributes directly to the model
So it appears it doesn't work. Anyway it's difficult for me to insert my Data Annotation on the MODEL itself because it's created via T4 hence if I edit it and then re-run the tool it will remove all my changes.
There is a pretty strong consensus around SO and the MVC blogosphere that you shouldn't annotate your business/crud/domain classes with attributes. Not only is your entire MVC stack becoming dependent upon your business/database classes but you'll quickly end up with multiple context scenarios ( same Model, different validation rules ) that are impossible to validate with just a single model.
Use separate view models for your screens, annotate those.
Based on your comment: "Data Annotation on the MODEL itself because its created via T4 hence"
What I'm trying to say is put your dataannotations on your viewmodels, leave your POCO models alone.

Resources