How entity framework reveals properties and types of a code first entity in runtime? - entity-framework

I just want to know how Entity Framework internally works to reveal properties and their types in runtime, particularly in case of Code-First approach, where there won't be system generated code. Can some body give some heads up? I don't think System.Reflection was being used implicitly?

Code first was first presented to developers as part of the EF Feature
CTP1 in June 2009 with the name “code only.” The basic premise behind
this variation of using the EF was that developers simply want to
define their domain classes and not bother with a physical model.
However, the EF runtime depends on that model’s XML to coerce queries
against the model into database queries and then the query results
from the database back into objects that are described by the model.
Without that metadata, the EF can’t do its job. But the metadata does
not need to be in a physical file. The EF reads those XML files once
during the application process, creates strongly typed metadata
objects based on that XML, and then does all of that interaction with
the in-memory XML.
Code first creates in-memory metadata objects, too. But instead of
creating it by reading XML files, it infers the metadata from the
domain classes (see Figure 1). It uses convention to do this and then
provides a means by which you can add additional configurations to
further refine the model.
ModelBuilder will now take this additional information into account as
it’s creating the in-memory model and working out the database schema.
By Julie Lerman

Related

What's the point of running an EF migration when you can SQL directly in database?

How to create View (SQL) from Entity Framework in ABP Framework
Not allowed to post comments because of reputation. Just trying to get more information on connecting a database to an Entity Framework, without having to switch to a code-first development style. View selected answer's response (he told the OP to basically do the same thing he was going to do in the DB but with EF, and then added an extra step where EF "...ignores..." the previous instructions...
I want to create tables and design database directly in SQL, and have the csharp library just read/write the table values (kind of like how dapper function where it isnt replacing your database, just working along side of it).
The tutorials don't talk about how to integrate your databases with your project. It either brushes over the subject, ignores it completely, or discusses how to replace it.
I don't want to do any EF migrations (i dont want/need to destroy/create database everytime i decide to run, duplicate, or transfer project). Any and all database back-track (back-up/restore) should be done with and thru SQL (within my work environment).
Just to be clear on exactly what i'm trying to learn:
How does somebody who specializes in database administration (building database schema, managing and monitoring data, and has existing database with data established) connect to project to fetch data (again, specifically referencing Dapper's Query functionality).
I want to integrate and design micro-services, some may share the same database connection or rely on another. But i just simply want to read data in a clean strongly-typed class entity, and maybe deal with insert/update somewhere else if i have to.
I would prefer to use Dapper instead of EF, but ABP is so heavily integrated with EF's design, it's more of a headache to avoid it, than it is to just go along with.
You should be able to map EF under ABP the same way as any other project using DB-first configuration.
The consistent approach I use for EF: (DB-First)
Define entities to match the table/view structure.
Define configuration classes extending EntityTypeConfiguration<TEntity> with the associated ToTable(), HasKey(), and any HasMany/HasRequired/HasOptional for relationships as needed.
In DbContext.OnModelCreating: modelBuilder.Configurations.AddFromAssembly(GetType().Assembly); to load all entity configurations. (assuming DbContext is in the same assembly as the models/configurations Substitute GetType().Assembly to point at the entity assembly.
Turn off Migrations. In DbContext constructor: Database.SetInitializer<MyDbContext>(null);
EF offers a lot more than simply mapping tables to classes. By mapping relationships between entities, EF can help generate optimized queries for retrieving data across those related entities. This can allow you to flatten data structures without returning unnecessary data, replace the need for views, and generally reduce the amount of data coming across the wire from the database to the application server.

Adding Hand-Built Models to an EDMX

I'm following an MSDN article on applying the Repository Pattern and the Unit Of Work Pattern to Entity Framework, but I'm stuck at the mapping between the custom-made domain models and the as-yet-nonexistant database.
The article has me create two simple POCOs, Employee and TimeCard. It also walks through creating generic repositories and custom implementations therein. (I'm using the custom repositories so I can try to keep EF dependencies in the data access assembly.) However, they sort of glaze over an important step in the mapping. The article says:
With the POCOs in place we can create an Entity Data Model (EDM) in Visual Studio (see figure 1). We will not use the EDM to generate code for our entities. Instead, we want to use the entities we lovingly craft by hand. We will only use the EDM to generate our database schema and provide the metadata EF4 needs to map objects into the database.
The "Figure 1" it references is here:
But that's all it says on the subject. There's an aside on how to generate POCOs from an EDMX. There's lots of information via Google on how to generate POCOs, generate EDMX from a database, etc. But in this walk-through we already have the POCOs and I need to use them in the EDMX which would, in turn, generate the database (I'm assuming, based on other code-first walk-throughs).
I've added an "ADO.NET Entity Data Model" to the project, which is basically a blank canvas. But I'm not seeing how to add my existing POCOs to that canvas. Do I have to re-create them manually on the design surface (which would be a pretty significant duplication problem in a larger domain)? If so, how do they map to the existing ones?
Typically when you use the designer the flow is the opposite - you create the model with the designer (or create/update the model from the database) and then the code is created for you. The created code can be either the EF1 style code with entities derived from EntityObject and attributes etc. which is created with a Single File Generator which is a part of VS (Code Generation Strategy set to "Default") or the code can be created with T4 templates (Code Generation Strategy set to "None") in which case you need to add T4 templates to your project. EF matches POCOs with Entities from the edmx file by convention (names of entities have to be the same, names and types of properties have to match etc.). In the article for some reason they went the opposite way which is weird since it requires that you create all the entities and relationships with the designer manually (since the designer does not know how to create entities from the code) and make sure that the requirements for the conventions (you may not even be aware of some of them) are met. However when you start with code the better approach is to use the EF Code First approach and skip the designer entirely. Code First can create database from your code. It also contains migrations feature which allows evolving your database along with your code. Finally (as you seem to use Visual Studio 2010) you could use EF6 which allows using all the goodness that was previously only available on .NET Framework 4.5 to be used on .NET Framework 4. See here for more details: http://entityframework.codeplex.com/
*the names are going to change in the new version designer that supports EF6 and works with Visual Studio 2012 and Visual Studio 2013
EDIT to address questions from the comment
If you would like to use Code First would use the DbContext API which is a streamlined wrapper of the ObjectContext API. Here is a walkthrough that should help get you started.
You can still use Code First if you have an existing database - the difference is that you will not be able to use migrations. The easiest way to get started with this is to use EF Power Tools. Take a look at this tutorial to see how to do that.
More help here

Using my own domain model objects with .edmx in Entity Framework

I have a domain model architecture in which my domain/business objects were created based on the problem domain and independent of any knowledge of the physical data model or persistence structures. So far I'm on track because it's perfectly acceptable and often the case that there is an impedance mismatch between the domain model and the data model. A DBA created the database for getting the data they required, but it does not encapsulate the applications entire domain model or design.
The result - I have my own set of domain model objects. However all of the fields that need to be persisted do exist somewhere or another within my domain model, but not necessarily in the shape that my auto generated .edmx POCO entities have them. So I have all the data, it's just not in the perfect shape exactly like the tables in which auto generated POCO entities are created from.
I have seen a few posts on this topic like converting POCO entity to business entity and Entity Framework 4 with Existing Domain Model that make statements like the following:
"Create the entities in your entity data model with the same names as
your domain classes. The entity properties should also have the same
names and types as in the domain classes"
What!? No way, why should I have to make my domain model be reshaped to POCOs that are modeled exactly after the data model / table structure in the database? For example - in my case of having 5 given properties, 2 might be in class 'A' and 3 in class 'B', whereas a auto generated POCO class has all 5 in its own class 'A'.
This is the entire point, I want separation of my object model and data model but yet still use an ORM like EF 5.0 to map in between them. I do not want to have to create and shape classes and properties named as such in the data model.
Right now my .edmx in EF 5.0 is generating the POCO classes for me, but my question is how to dissolve these and rewire everything to my domain objects that contain all this data but just in a different shape?
By the way any solution proposed using a Code First approach is not an option so please do not offer this. I need some guidance or a tutorial (best) using EF5 (if possible because EF4 examples are always inheriting POCOs from ObjectContext) with wiring up my own business objects to the .edmx.
Any help or guidance is appreciated, thanks!
This sounds like exactly the use case of Entity Framework. I am making a few assumptions here. First that when you make this statement:
"I have a domain model architecture in which my domain/business objects were created based on the problem domain and independent of any knowledge of the physical data model or persistence structures."
That you mean this domain was created in the EF designer? But then you say:
"However all of the fields that need to be persisted do exist somewhere or another within my domain model, but not necessarily in the shape that my auto generated .edmx POCO entities have them."
This sounds to me like my first assumption is incorrect.
Next, you dismiss code first? If your domain model/business objects are code based and you want to persist them to a relational database, that is exactly the use case for code first. You have the code, now you need to create your DbContext and map it to your physical model.
However you dismiss that... so some thoughts:
If you have a domain model of code based business objects and you have an EDMX that is used for other things I think you would want to create a repository layer that uses something like auto mapper or manual projections to query your Entities and return your business objects.
If you have a domain model of code based business objects and you have an EDMX that is not used for other things other than persisting your business objects I would say that you need to express your domain in an EDMX and then map it onto your existing database. This is really the use case for an ORM. Having two domain models and mapping from one model to the other where one model matches your domain and one matches your database is adding an extra un-needed layer of plumbing.
The latter approach above is what is called "Model First" in EF parlance. There are several articles written about it although the bulk of them just generate the db from the model. You would not do that step, rather you would map your entities onto your existing database.
The basic steps for this are to "update from the database" not selecting any of the db objects (or entities would be created). Or, you can take your exiting .edmx in the designer (which is sounds like you have) and modify the entities to match your business domain. Or just delete all the entities in your EDMX model, create your entities as you want them, and then map them all.
Here is a jing I made where I use the EF Designer to bring in the model store (the only way to do this is to allow it to generate entities) and then delete the entities allowing the Store information to stay by clicking NO when it asks if you want to delete the table info.
http://screencast.com/t/8eiPg2kcp
I didn't add the POCO generator to this, but if I did it would generate the Entities in the designer as POCO classes.
The statement quoted above is not suggesting that you rewrite your domain objects to match your pocos, it is suggesting that you update the edmx to match your domain model.
In your example you could create an entity in your edmx that maps all 5 properties from both tables and EF will manage the mapping to and from the single generated Poco onto your tables.
Of course this means that you then have duplicate domain objects and pocos, meaning you would either have to manually convert your domain objects to pocos when interacting with EF,
or you could define your domain data objects as interfaces and provide partial implementations of the pocos that essentially identify each poco as being a concrete implementation of a domain object.
There are probably several other ways to skin this particular cat, but I don't think that you can provide predefined c# objects for use in an edmx.
One approach might be to select into a ViewModel (suited to your particular business logic) and automatically map some data from the context into it like so https://stackoverflow.com/a/8588843/201648. This uses AutoMapper to map entity properties from an EF context into a ViewModel. This won't do everything for you, but it might make life a bit easier. If you're unhappy with the way this occurs automatically, you can configure AutoMapper to do things a bit differently (see Projection) - https://github.com/AutoMapper/AutoMapper/wiki/Projection
You might know this already, but its also possible to automatically generate POCOs from your EDMX using t4 - http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d. If you define the templates to generate partial classes, you can then have another partial class with your custom properties for that POCO. That way you can have most properties automatically populated, but have other custom properties which you populate with custom rules from your context/repository. This takes a lot of the monotony out of generating these, and you can then focus on reshaping the data using the above technique.
If you're seriously unhappy with both, you could always map a stored procedure to get the exact field names that you want automatically without needing to stuff around. This will of course affect how you work with the data, but I have done it before for optimisation purposes/where a procedure already existed that did exactly what I wanted. See http://msdn.microsoft.com/en-us/data/gg699321.aspx

Defining business objects in Entity Framework

Trying to understand Entity Framework. My approach is database first. However I would like to define other entites in the model that is closer to my business objects. I guess I could write queries in the db and include them in the model. But I would also like to define entirely new entities in the model though they would be based on underlying tables in the db. How do I do that - does anyone know a tutorial?
Regards
Bjørn
db Oldtimer, EF Newbie
Database first means that you have existing database and you can either create model by updating from database or manually. You can use wizard to create initial model and modify it manually to define new entities but you must not use update from database any more or some of your changes will be deleted. Also your custom modifications must follow EF mapping rules (for example it is not directly possible to map multiple entities to the same table except some more advanced mapping scenarios like splitting and inheritance) and some of them (custom queries) must be done directly in EDMX source (XML) because designer doesn't support them - this requires more complex knowledge of EF mapping and it will be definitely hard for newbie.
You can check specification of that XML. For entities mapped to custom queries you will have to use DefiningQuery element in SSDL part of EDMX.

Compose queries across Entity Data Models

Is there a way to compose queries from 2 different entity models if the models are hitting the same underlying database.
The scenario I have is this:
I have a framework that uses EF for data access.(EDM 1)
I have a client application that uses services of the framework and also uses EF for it's own data access.(EDM2)
There are situations where I need to compose queries and join on entities that span the 2 EDMs.
Is there a way to do this without getting the data in memory from the first EDM and then apply additional predicates/joins in memory from the entities of the 2nd EDM?
I hope I'm articulating this the right way
EDIT
#Ladislav Mrnka:
The first EDM is the data access layer for a reusable framework.
It doesn't make sense to couple the EF generated entities from this EDM with
those of the consuming client
It defeats reusabilty of the API if I did this and I'd have to carry around additonal bloat
(EF metadata and DB tables of the client) everytime I wanted to redeploy the framework.
Also this would make managing the model in the designer unwieldy.
I'm currently using what you mention n item 7 as the solutuon and the performance is abysmal
due to the fact that I have to end up returning more data(i.e. entities) than needed from framework using
EDM1 and then filter out the ones not needed based on predicates/conditions based on value of
properties from entities in the second EDM. End result is a huge performance degradation and an unhappy DBA.
For this reason I ended up pushing the logic needed to retrieve the entities
to a SPROC in which I can access the tables that both EDMs use and apply the predicates needed
and have the entire query run in the DB as opposed to bringing the data in memory
and then filter out unnecessary ones.Downside is that I can't use LINQ
Item 8 that you mention sounds interesting but from what it sounds like I doubt that
you get strong typing at design time, or do you?
Can you upload your code sample someplace so that I can try it out?
Important edit
There is no build in support for achieving this with two ObjectContext types. Your query must always be executed against single ObjectContext.
Probably the best way to go: This was interesting enough for me to try it myself. I started with very simple idea. Two EDMX files (used with POCO T4 generators), each containing single entity. I take metadata description from second connection string and added it to first connection string. I used ObjectContext and ObjectSet directly. By doing this I was able to query and modify both entities from single ObjectContext instance. I also tryed to create query joining entities from both models and it worked.
This obviously works only if both EDMX map to the same database (same db connection string).
The important part is connections string:
<configuration>
<connectionStrings>
<add name="TestEntities" connectionString="metadata=res://*/FirstModel.csdl|res://*/FirstModel.ssdl|res://*/FirstModel.msl|res://*/SecondModel.csdl|res://*/SecondModel.ssdl|res://*/SecondModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.;Initial Catalog=Test;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
This connection string contains metadata from two models - FirstModel.edmx and SecondModel.edmx.
Another problem is to force EF to use mapping from both these files. Each EDMX file must define unique container for SSDL and CSDL. ObjectContext offers property called DefaultContainerName. This property can be set directly or through some constructor overloads. Once you set this property you bind your ObjectContext instance to single EDMX - for this scenario you must not set this property. Omitting DefaultContainerName can have some consequences because some features and declarations can stop working (you will get runtime errors). You should not have problems with POCO unless you want to use some advanced features. You will most probably have proplems if you are using Entity objects (heavy EF entities. All methods using entity sets defined as strings are dependent on container. Due to this I suggest using such configuration only when necessary - for cross models queries.
Last problem is generating entities and "strongly typed" derived ObjectContext. The way to go is modify T4 template so that one template reads data from multiple EDMX files and generates context end entities for all of them - I already doing this in my project and it works. Default T4 implementation doesn't follow needed approach described in previous paragraph. Derived ObjectContext from default T4 implementation is dependent on single EDMX and entity container.
This part has been written before previous edit.
I'm leaving the rest of information just because some of them can be useful in other scenarios including work with multiple databases.
ORM like entity framework operates on top of mapping between object world and database world. In EF the object world is described by CSDL, database world is described as SSDL and mapping between them is described as MSL (all are just XML with well known schema). At design time these descriptions are part of model stored in EDMX file. During compilation these descriptions are extracted from EDMX and by default included as resource files to compiled assembly.
When you create instance of ObjectContext it receives connections string which contains reference to CSDL, SSDL and MSL resource files. SSDL or MSL do not specify include element to add information from other files. CSDL offers Using element which will allow you reusing existing mapping but this feature is not supported by designer. ConnectionString is used to initialize EntityConnection instance which is in turn used to initialize ObjectContext's MetadataWorkspace (runtime mapping information). Also ObjectContext doesn't provide any functionality of nesting multiple contexts into hiearchy. Connection string can't contain reference to multiple instances of these files. Edit: It can. I just tested it. See the initial paragraphs.
When you run Linq or ESQL query on the instance of ObjectContext it usese MSL to map your entities or POCO classes (defined by CSDL) into DB query (defined by SSDL description of database tables). If it doesn't have this information it will not work (and it can't have that information if it is stored in separate EDMX).
So how to solve this problem? There are several ways:
Always consider: Merge your mapping into one file (if multiple files are used for same database). That is supposed way to use EF and as you mentioned you are querying same DB so two EF models are not needed.
Duplicate entity description in second model. If you use EF4 and POCO you can map same descriptions from multiple models into one POCO class definition. I don't like this solution but sometimes it can help.
Define DB View or Stored procedure containing your query (or core of your query) and map it in one model to new entity.
Use DefiningQuery in one model (you will probably need 3rd one if you use Update from database feature) and map it to new entity. DefiningQuery is custom SQL query defined in SSDL instead of table or view description.
Use Function with custom CommandText specifying DB query. It is similar to using DefiningQuery and it has the same limitation. You must manually (in EDMX) map the result of the function into new complex type (another difference to DefiningQuery which is mapped to new entity).
Define new type for result of the query (properties of the type must have same names as returned columns in query) and use ObjectContext's ExecuteStoreQuery (only in EF4).
Divide query into two parts each executed separately on its own context and use linq-to-objects to get result. I don't like this solution.
This one is only high level idea - I didn't try it and I don't know if it works. As described above runtime mapping is dependent on the content of MetadataWorkspace instance which is filled from EntityConnection. EntityConnection also provides constructor which receives MetadataWorkspace instance directly. So generally if it would be possible to fill MetadataWorkspace from multiple EDMX you will not need multiple ObjectContext instances but your mapping would be still separated into two EDMXs. This would hopefully allow you writing custom Linq queries on top of two mapping files). Edit: It should be possible because it is exactly what EF is doing if you define multiple mappings in connection string.
Use CSDL Using feature for breaking the model into multiple reused parts.