EF 4.x generated entity classes (POCO) and Map files - entity-framework-4

I have an MVC 4 app that I am working on and using the code first implementation except I cheated a bit and created my database first then generated my entity classes (poco) from my database using the EF power tools (reverse engineer). I guess you can say I did database first method but I have no edmx file just the context class and my entity classes (poco)
I have a few projects in the works using MVC and EF with pocos but just the one project I used the tool to generate my pocos from the database.
My question is about the mapping files that get created when I generate my pocos using the tool. What is the purpose of these Map files? I figured the map files are needed when generating the db from the model like with the true code first method, in my case where I am using a tool to generate my model from the database do the map files have any influence on how my app uses the entity classes?

The mapping files are to fluent files help Code First generate the database from your model, as well as help EF create the proper relationships.
They can map properties - things like setting a primary key, max length, data type.
They can also map relationships - set things like foreign keys, and defining relationships that don't follow standard CF naming conventions.
Even though you're not generating your database from the app, CF will use this system to ensure that the database it's pointing to is compatible with your model, and in the case of foreign keys and things setup related properties. For example, if you wanted to name a FK something other than NavigationPropertyId, you would need fluent to tell the engine what property to set in the database.

Related

Why is it called 'Code First' from database in EF

I've made an application in ASP.NET MVC. I first created an database in SQL Server and then installed the Entity Framework in Visual Studio and used the Entity Data Model Wizard, I selected the 'Code First from database', and it generated the derived DbContext Class and the models from the database.
My question is basically, why is it called 'Code First' when all the classes are generated based on the database - I've basically written no code, apart from the SQL.
Normally Code first refers to generating the database from your POCO but typically when you are targeting an existing database you can have the VS tools create the classes for you to get up and running quickly.
That is the impression I go from typing Code First from database into google.
Code-First from an Existing Database:
Entity Framework provides an easy way to use code-first approach for
an existing database. It will create entity classes for all the tables
& views in your existing database and configure it with
DataAnnotations attributes and Fluent API.
Additional source:
ScottGu's Blog - Using EF “Code First” with an Existing Database
EF “Code First” works great with existing databases, and enables a
very nice code-centric development approach with them. In particular,
it enables you to use clean “plain old classes” (aka POCO) for your
model objects, and cleanly map them to/from the database using either
the default mapping conventions or by overriding them with custom
schema mapping rules.

Repositories calling existing stored procedures

Let's say I am developing a few ASP.NET MVC applications working with data in an existing database just over by stored procedures, no and never linq to entities or anything else. That database contains lots of schemas and all my web applications needs the different schemas as well.
Here is my point:
I have a x.Model project in my solution that contains my ADO.NET Entity Model to create return types for all of my stored procedures in my existing db.
I have x.Repository.y projects in my solution where y is the schema name in the database. These projects contains classes having functions to call the stored procedures from the appropriate schema by ADO.NET Entity Model's context. So I have to have reference of x.Model in these repository projects.
And I have ASP.NET MVC projects that uses the necessary injected repositories from x.Repository.y projects. I use some of these return types of stored procedures as models in my views, so I need a reference to x.Model project too. But in that case this reference gives all the context to client web applications. I don't want my whole or partial db entities is reachable in my web applications. I just want them to know about necessary repository classes.
Is it possible? How can I do that?
If I remove x.Model project and create the ADO.NET Entity Models containing just the appropriate schemas stored procedures in my x.Repository.y projects then the referencing web applications again knows about this schema's whole db entities.
Thanks in advance,
Maybe, better way to use Model First or Code First approach. So, you can describe pure (without references to DbContext and other Data classes) entities. Then, create mapping in x.Repository project. And referene your Model to ASP.NET MVC site. So, you will have only entities and repositories but mapping and DbContext will be hidden inside one reference (you can mark mapping classes as internal).

Handling foreign keys in multiple contexts/domains using Entity Framework Code First and Migrations

I'm building a new system that utilizes data from an existing legacy system. A requirement is for our application to use the same physical database but a different schema for isolation. Our application will need read access only from the dbo schema, but our new structure will have foreign keys from the dbo schema so we'll need to enforce that.
I'm planning on creating two different projects with two different contexts. This will facilitate using Reverse Engineer Code First from EF Power Tools on the dbo schema, and using EF Migrations on our new schema. However, I'm unsure how this approach will handle Foreign Keys across contexts/domains. How would I map these so Migrations interprets it correctly?
If you use different schemas and\or different contexts, that means this data can be stored anywhere, even at different storages (files, azure, services). You should not use explicit foregin keys across across contexts/domains. You have to make separate queries to each contexts.
If you really need to do that, you can use databse VIEWS with any joins you need (even from other server). Then just map our EF entity to view:
[Table("MyView")]
public class MyEntity {...}
Obviously, it will read-only entity.

MVC 4 + Entity Framework 5 + Stored Procedures

I'm just now teaching myself MVC4 (did webform for years), and I'm
frustrated - but not about MVC which is pretty good. Entity Framework
is...well
I'm using VS2010.
The problem
We have a real database, you know normalized with like foreign keys and stuff. But every example I find for Entity Framework is direct to the table, but we rarely have a straight table pull - out side of populating dropdowns and such. All of our frontend calls hit a Stored Proc (how old school! expletive deleted)
I love the Model architecture of MVC where you define the attributes of the data coming from the data source - Display Name, Ranges, DataType. etc. So I definitely want to keep this.
Entity Framework and MVC do not want to play well in this senario. I created my edmx file (with SPs only), did my function import for a SP, everything is good....'til now.
Can't Create a Controller from the edmx/designer - Enter Controller Name, pick MVC controller with read using EF, pick the model class that is the FuntionName_Result, and for context pick the ...Entities name. FAIL Unable to retrieve metadata
OK, so now I try EF 5.x DbContext Generator, update the file name and boom I have a model and context - awesome now I can do the cool MVC stuff, lets rebuild the site....oh the horror - everything has been previously defined.
I tried generating the edmx in a different folder and/or deleting it after the DBContext generator, still can't create Controller.
'blah' is not part of the specified 'Context' class, and the 'Context' class could not be modifed to add a 'DbSet' property to it. (For example, the 'Context' class might be in a compiled assembly.)
IF I manually add the DBSet, I'm back to unable to retreive metadata - I am assuming this is happening because it can't connect to the DB. I don't know where to tell it to use the connection string in web.config. - if this is the problem
Here lies dead my MVC hopes of a brighter future.
What am I missing?
I am not married to EF, so if there is a better way to access databases (without writing all the code from scratch) I'm here to listen.
Thanks
Entity framework relies heavily on conventions. It takes a little bit to get used to. For example for connection strings... If entity framework doesn't find a connection string with the same name as your DBcontext class it just makes one (i think it defaults to using the project name as the database name). If this database doesn't exist it will create it locally as a sql express DB. This leads to the kinds of errors like the ones you are reporting.
If you want to define the connection string for entity framework all you need to do is provide a connection string in the web.config. Again conventions.... the connection string should be named the same as your DBContext class and entity framework will just find it.
<connectionStrings>
<add name="MyDbContextClassName" connectionString="..." />
</connectionStrings>
On an architecture note, IMHO ORM's are defiantly the way to go for new application development. It makes getting data into and out of your database soo much easier. That said it is a Big paradigm shift if you are used to accessing everything via sprocs and direct queries to the DB. Don't give up on it. It will frustrate you at first just like picking up any new tech, but it's well worth it in the end.
I have used entity framework and nHibernate for ORM in the past. The thing that I like about entity framework is that if you use code first migration most of the really annoying, tedious, and error prone column mappings are auto generated for you (again using conventions). You sometimes still end up having to do a little mapping but those cases are pretty rare. Maybe a little less rare if you already have a database since your column names will probably not always match entity frameworks conventions. Anyway... This is a big plus in my book and why I would defiantly favor EF over nHibernate.
If you already have a database, with stored procedures you do not need the EF 5.X DbContext Generator. Create either a folder in your project or a new project in your solution for your data access. In that folder/project add a edmx file and configure it to an existing database using the wizard. At this stage you can pull in your stored procedures.
If you open the edmx file, you can go to the model explorer tab and manage the imported functions (stored procs) and their return types.
Once you have that, In your controller, rather than using an instance of DbContext you can just use an instance of your EF Entities. So if you called your edmx 'MyDbAccess' you should be able to use MyDbAccessEntities which will then allow you to access the stored procedures.
I in your App.config file check your
<connectionStrings>
After check if your stored procedures are added in the model context file
YouDBModel.Context.tt
> YourBDModel.Context.cs

Manually loading associations in EF model

I need to use parameterized table-valued functions to retrieve the data for an association (the TVFs abstract the actual database tables), but would like to use all the good stuff provided by the EF. So looking at the generated Navigation Property code from the EDMX, I see that the RelationshipManager wraps the population etc. of the association.
So my question: can I retrieve the results I need from the DB (via the TVFs) and attach them to the context before the generated calls to the RelationshipManager, and also stop the RM itself from accessing the database?
EF4 does not support TVF. TVFs are available only in .NET 4.5 where you can use them in Linq-to-entities queries. .NET 4.5 also by default uses POCO entities which are now strongly recommended where RelationshipManager is not used inside the entity (except dynamic proxies for lazy loading).

Resources