MVC 4 + Entity Framework 5 + Stored Procedures - asp.net-mvc

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

Related

Entity Framework 7 and ASP MVC 5 - simple tasks

I am sorry if I am asking something that has an obvious answer, but I have spent and entire day searching for resources on the subject and I fail to find or understand how to do a few basic thing with EF7.
So, here is my question.
I have an ASP MVC 5 (VNEXT) website and I am using Entity Framework 7. I have an existing database, thus I am working database-first.
So far everything was fine. I installed everything required to get my DNX EF commands up and working; I scaffolded a dbContext and I got all my tables as classes and a dbContext class.
Everything fine, all well. I was happy and continuing with my work.
However, I got to a point where I wanted to make a property of one of the generated (table) classes Required, because I use jQuery unobtrusive validation.
I have the following resource as a reference: http://ef.readthedocs.org/en/latest/modeling/required-optional.html
My first wonder is, according to this source, in the FluentAPI the property has been marked as .IsRequired(). I believe, making it required here is a whole other thing that has nothing to do with unobtrusive validation. So, the next thing explained is simply - go to your class and add the Required data annotation.
This is all fine and well, and after adding it, it works as it should.
But I immediately wondered - well, I am modifying the generated classes, am I not going to lose those changes once I update the model?
Which leads me to my final problem - I searched for a long time, I even played with the help menu of DNX EF, but I am unable to find the right way to update the dbContext and generated models after I make changes to the database.
I believed this to be something quite trivial but to my surprise I am unable to find a resource explaining how to do the update.
Can you point me in the right direction, and tell me how to update EF generated models and context after I make changes in the database schema, and what is the best way to add annotations to the properties of the generated classes?
The general consensus is that you shouldn't use your database entities as input from users directly. Instead, use ViewModels, verify those against your validation rules, then map them to database transactions.
As asp.net MVC developer I use database first and updating database is a big head ache so I use Metadata approach and create ViewModels which helps allot.

EF database migrations

I'm working on an MVC4 application that uses Entity Framework 5, database migrations, and the asp membership api. In my development environment I can delete my database entirely, run a package (.zip), refresh the page and all works as expected; a database gets created, the seed method is called and some default values are stuck into the database.
Perfect, really easy too! But.....yes, there is always a but!
When I go to deploy this same package(only changed the db connection string) and run this in a remote environment, the behavior changes. Again, if I go in and delete the database entirely, run the package (.zip), refresh the page, the database gets created with only the asp membership api tables. I've checked the connection string, and that is for sure, not the cause, or else the database and membership tables couldn't get created.
I am aware of using the nuget package manager, which is really a powershell instance, but I am not using it since it cannot be used in the production environment. I'd like the package to handle it all, and in my test environment, it works perfectly.
Does anyone have any suggestions? Could this be a side effect of mixed migration history?
Thanks in advance!
The default MVC4 Internet Application project messes up a lot of people. Microsoft wanted to demonstrate the SimpleMembership functionality, which requires an EF context, but it's not common sense that you have to actually modify this portion to effectively use the rest of your app.
So, a little primer on how Entity Framework works will help clear up why this happening I think.
Entity Framework (at least version 5, it may change in 6 or successive versions) only allows one DbContext for your application. Most likely, you have at least two, the AccountsContext that was autogenerated by the project template and the context you use for the rest of your application. If you were to turn off automatic migrations and attempted to generate a migration, EF would helpfully tell you that you need to specify which context to use. However, automatic migrations are the default in Code First, very few disable that, and thus very few ever get alerted.
When automatic migrations are enabled, and you have no existing database, EF happily (and silently) creates the database for you from your context. But, what if you have multiple contexts? Well, the other nasty little feature of EF is that it creates the database just-in-time. So, which context gets used is a function of which one is accessed first. Nice, huh? So, if you attempt to do anything like a logon, then the database is created from the AccountsContext and then, when you try to access something from your app's context, the database already exists, and EF does nothing.
So, what to do about this? Well, you need one context to remove ambiguity. You can still have more than one context if you want in your app, but you have to essentially tell EF that all the other contexts are database-first, i.e. don't do anything.
public class AccountsContext : DbContext
{
public AccountsContext()
: base("name=YourConnectionStringName")
{
Database.SetInitializer<AccountsContext>(null);
}
...
}
public class MyAppContext : DbContext
{
public MyAppContext()
: base("name=YourConnectionStringName")
{
}
// All your entities here, including stuff from AccountsContext
}
MyAppContext will be your "master" context, which will have every entity in your database that EF should know about. The base call on both serves to take EF's guessing out of of the way and explicitly make sure everyone is one the same page as to what database connection should be used. Your AccountsContext is now essentially database-first, so it won't spark EF to create the database or attempt any migrations -- that's what MyAppContext is for. You can create other contexts in the same way as AccountsContext to break up your app's functionality; you just have to mirror any DbSet property declarations into your "master" context.
Julie Lehrman calls this concept "bounded contexts" in her book, Programming Entity Framework: DbContext, and presents a generic class you can inherit all of your "bounded contexts" from, so you don't have to specify the connection string name and set the database initializer to null each time.

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

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.

Using two different databases simultaneously using Entity Framework

I'm using Entity Framework 4 in an MVC3 project. I'm trying to access two different databases (A and B):
Databases A and B are completely different and unrelated.
Database A is a 'code first' SQL compact database.
Database B is a 'database first' SQL Server database.
I have straightforward queries on either database, no linking or cross-database joins.
Either database connection works if I remove the other DbContext from the project.
Now, when I try to query from database A, I'm getting an Exception "Could not find the conceptual model type for ".
I can't imagine that EF doesn't let you use different databases, so my question is: do I need to do something extra when creating a new instance of the appropriate DbContext, in order for this to work?
I stumbled across this thread while trying to resolve the "Could not find the conceptual model type for" exception.
I am using EF 4.2 with multiple models. I implemented DbContext with one of my models to "try it out". When I compiled and ran, I received the exception above for an entity in a completely different model on a completely different database!
After much hassle I finally implemented DbContext to the other two models and everything ran fine.
I know this doesn't necessarily answer the question, but I wanted to leave this here for anyone else that has the same issue and stumbles across this post.
Make sure you don't use the same entities name for both edmx files. You can change it manully opening a edmx with xml editor right clicking the file and open with.
Note that for some security reasons you can't nest the contexts. They can only be used separated.

EF4 and ASP.Net MVC to Test and Develop without mapping to an underlying database (until later)

I want to develop an ASP.Net MVC application with EF4 Model First design and only generate the actual database much later, ideally at the end of the project.
Based on some of the ideas here:
http://elegantcode.com/2009/12/15/entity-framework-ef4-generic-repository-and-unit-of-work-prototype/
I want to create something like an InMemoryObjectContext for testing and development and use IOC to switch to the SQL Server implamentation (EF generated) for UAT and production.
Is this wise?
Is it possible? If so, does anyone have any suggestions?
Does EF always need an underlying database in order to track changes, commit etc?
I've tried creating a model first but as soon as I add properties I get the following errors:
Error 2062: No mapping specified for instances of the EntitySet and AssociationSet in the EntityContainer Model1Container.
and the warning:
Running transformation: Please overwrite the replacement token '$edmxInputFile$' with the actual name of the .edmx file you would like to generate from.
The error doesn't stop the application running but worries me. I'm very very new to EF so I apologize if this is way off the mark or a dumb question. I'm hoping to get some good advice while I sit for the next few days and watch videos and read articles.
Thanks
Davy
At the very least you need mapping information "filled in". You can fill these fields with nonsense if you don't want to work against the underlying database.
If your doing Model first, right click on the designer canvas and select, "Generate Database from Model". This will automatically create convention based mappings for you without defining tables and columns. You don't even need a valid db connection to do this.

Resources