I’m trying to learn how Entity Framework core uses C# classes to create the DbContext model. I assume it discovers types based on DbSets then calls the same model builder that is passed to OnSchemaCreating, I just can’t find the code/logic in the repository that does this (or perhaps there is another approach). Can anyone explain how this is done and point to the source code that does this?
Smit Patel from the ASP.NET team pointed me to the answer. There is a ModelSource abstraction that takes both a DbContext as well as some conventions. It customizes the the model based on DbSets on the DbContext class by simply adding an entity type for each DbSet, the remaining property/key/index configurations are all done by conventions.
Related
In previous versions of Entity Framework we could use EntityTypeConfiguration<TEntity> to configure the mapping for the entity of type TEntity on the constructor.
The other option is to set the mapping on the OnModelCreating method of the DbContext, but this other option is nice because we can leave each mapping in its own place.
Now I'm starting to use Entity Framework Core and I could not find the EntityTypeConfiguration<TEntity> class, so I believe things have changed.
Is it possible to create a mapping class in the new version of Entity Framework or for now we have to use the OnModelCreating?
Unfortunately, OnModelCreating is the preferred way to do it right now. The team (specifically rowanmiller) mentioned that:
I think we will probably do this, or something like it, but it is lower priority than some of the other features EF Core is missing at the moment.
https://github.com/aspnet/EntityFramework/issues/2805
If you read through the comments on that issue, there are some alternative ways to do it, but not "officially" supported ways other than OnModelCreating right now.
Is there a way in EF7 to force DbContext to create instance of my model by passing values to constructor not assigning them directly to the properties?
Docs tells me that I can interact with EF by providing it services. I found that IModelCustomizer is responsible for controlling how a model is created. But I'm not sure that if that is what I'm looking for nor how to implement that.
I'm new to Entity Framework (I'm using EF5), and I'm working on a test project to learn something about it.
Now I'm implementing some DAO classes to access DB following this tutorial (it's a bit old...)
I generated entity classes using Entity Data Model tool, but now I need all entities to inherit from EntityObject class.
Reading this I expected it to be so, but actually my classes inherit only from IObjectWithChangeTracker, INotifyPropertyChanged.
So I'm wondering if I'm doing something wrong...
Do I have to set some configuration in generation tool?
You need to use the correct template from http://msdn.microsoft.com/en-us/data/jj613116.aspx - one of those that are called "EntityObject Generator".
From MSDN:
Represents a combination of the Unit-Of-Work and Repository patterns and enables you to query a database and group together changes that will then be written back to the store as a unit. DbContext is conceptually similar to ObjectContext.
I though DbContext only handle the connection to the DB and the number of threads working against the DB.
Now I understand it contains the tracking mechanism? I thought this was in the ObjectContext.
So what is (in plain English) the difference between them?
DbContext is a lightweight version of the ObjectContext class, which is laid almost right on top of ObjectContext (there is even a way to get to the ObjectContext from just the DbContext). It's also a lot easier to use, IMO, and makes CRUD operations a sinch.
For better information, who better to look to than Julie Lerman for more info on the differences, as was brought into EF 4.1.
the DbContext is a smaller API exposing the most commonly used
features of the ObjectContext. In some cases, those features are mirrored in the DbContext
API. In other cases, the Entity Framework team has simplified more complex coding
by providing us with methods like Find or properties like DbSet.Local. But there’s
a big API lurking underneath that you may still need access to. For example, you might
want to work directly with the MetadataWorkspace to write generic code against classes
because that API can read the model more efficiently than reflection. Additionally, the
MetadataWorkspace is able to provide more information about the metadata than you
can discover with reflection, for example, for Key properties. Or you might want to
take advantage of a database-specific function that is exposed through Entity SQL,
which you can’t access from LINQ to Entities.
Or you may already have an application
written using the ObjectContext and you want to leverage the DbContext in future updates
without replacing all of the ObjectContext code.(Reference from Programming DbContext)
Object Context:
1.It support compiled query
2.It support self tracking of entities
3.It available for entity frame work 4.0 and below version
4.It is not thread safe.
5.It is best for DB first and model first approach.
Database Context:
1.It does not support compiled query
2.It support not self tracking of entities
3.It available for entity frame work 4.1 and above version
4.It is thread safe for static and share member(public).
5.It is best for DB first and model first approach and code first approach.
I am new to Entity Framework 4.0, using it with C#, and currently experimenting with its features.
What I noticed is that, like with most similar ORMs, it relies on an Context object to deal with the data-manipulation and CRUD statements generation done on the generated entities.
This means that if I want to save the changes back to the database, I always need to be able to have access to a reference to the ObjectContext that has instanciated the entities.
It is fine and all if the context has been created in an accessable scope (same method, for example), but what if I pass an entity or and entity set to a method and want this method to save the changes? It looks like the only easy way is to pass the ObjectContext along with the parameters.
Another solution would be placing the ObjectContext in some sort of global variable.
Needless to say, I find styling and maintainability issues to both of these approaches.
In short, the best way I can imagine is getting a reference to the ObjectContext from the entity or entity set.
I know that it isn't possible by default.
I have found a method showing adding an extension method to get the ObjectContext from the entity. However, it only works for entities with relationships and calling this method is expensive according to the author.
I was thinking about maybe modifying the T4 template to add a Context property to all my entities and fill it automatically on entities' instanciation.
I have already modified T4 template once to have Entity Framework enforce Max Length on my generated classes (by following Julie Lerman's Programming Entity Framework 4 book).
I can't say I really enjoy the T4 syntax so far, but if that's the best/only way, so be it...
Has anyone already done so and what would be the best way to handle this and willing to share his T4 template or explain what are the best partial methods or events to hook into to get this done?
Is there any major downside in using such an approach?
I am thinking that having so many references to the ObjectContext may hinder/delay its ability to be recollected by the GC if some of my entities remain in scope but I actually have no use anymore for the ObjectContext.
Many thanks.
If you need to pass object context as parameter together with your entities you are doing something wrong.
Usually context is needed only in well defined layer. All classes from this layer which requires context to their logic can receive the context through some specialized class - context provider (it can also be called service locator). Context provider will hold current context instance in some storage - you can create your own or you can store it per thread, per http request, etc.
If they need more then one context instance in your classes you can modify your provider to work also as factory.
Another common approach is combined with dependency injection. You will pass the context to your classes through the constructor (or property) and you will have some bootstraper code which will do all necessary initialization for you (create required instances and pass all dependencies into them). Again you can pass a context or a factory. This is usually used together with IoC containers which will do the plumbing for you.
Once you have this infrastructure prepared you can pass your entity to the any initialized class from that layer and it will have the context available.