Entity Framework 5 - Code First Production Preparation - asp.net-mvc

As part of our intended migration from Linq2Sql to Entity Framework, we have created a small EF model consisting of ten entities. Because we are working with a legacy application we are using the 'code first' option and manually mapping our POCO objects to tables within the database. We do not want the Entity Framework code to update the database. I believe that the following is all I need to do to achieve this - I would appreciate confirmation as I was not sure whether the SetInitializer code should go here or perhaps in the Global.asax code.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<InboxDataContext>(null);
modelBuilder.Configurations.Add(new Subscribers.Mapping.DataSourceMap());
modelBuilder.Configurations.Add(new Subscribers.Mapping.SubscriberMap());
...
}
As part of this update, we have created a small test page (MVC controller and views) and added it to our main application project. During development and testing this has worked well. The only thing we did notice is that if we updated the underlying EF model, the initial page load seemed to take several minutes to render. I assumed this was because EF had to rebuild its views and mappings to reflect the changes - to my disgrace, I didn't worry too much about this as a) I don't have a full understanding of how this works and b) it only seemed happened on model changes.
This morning we loaded this update to the production server for initial testing and this time the initial load problem became much worse - so much so in fact that the test page never loaded.
So, to get to my questions:
Is there anything else I should/should not be doing to prepare my
application for production?
How can I improve the initial load performance?
How can I find out why the initial load on the production server
never completes - I am not seeing any error messages?
I did try downloading the Entity Framework Power Tools and running the 'Generate Views' option on the derived DbContext class, but since I could only run this in the development environment I was not sure whether this would work when copied to the production server - it didn't appear to.
I should mention that the development environment contains just one hundred records in the main table and the production environment contains almost one million records (same schemas), again I wasn't sure if this would make any difference.
Any help advice would be appreciated.
Thanks.

Firstly, if you are using an existing database then a better approach would be Model First. You can connect your Edmx to your current database and it will gather all the required mappings as they currently stand. It then also generates the POCO classes and DbContext (with EF5, you have to do it manually in <5). Using this approach may cut down on initialisation time as your code wont have to create a model at runtime.
Give this a try, and it might solve all your problems (I believe they are all related).

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 Code First project organization

I am having trouble getting started on my first attempt with EF and Code First mostly due to trying to find an efficent way to organize the project in Visual Studio. I wanted to try Code First so I pictured a set of class files in a separate project to describe the entites, like MyApp.Models. To build on that I imagine I need something like Fluent API to make sure the database is created the way I expect which is where I hit the first snag. I think the only way to do this is to define the context where EF generates the database. So where should that code creating the context be defined? In a separate project like MyApp.DAL? I'd also like to include Asp.Net Identity 2.0 which I believe is part of defining the context so that is included in that step. Next I assume I need to actually call the code so EF can generate the DB which requires at least a configuration setting for the connection string. Eventually I want an MVC app but maybe next is a console EXE like MyApp.ConsoleTest? Also I'd also like a Web API project which would serve the MVC app. I think those can be covered with something like MyApp.WebAPI and MyApp.ClientWebMVC. Perhaps later I could also create MyApp.ClientWPF which would leverage the work done with the Web API. Along the way I should also probably have something like MyApp.Common or Shared.Common to hold things like logging and error catching.
I think the first few steps around the entities and context are what trip me up the most. I want to try and organize the data part of the code so changes can be isolated from ruining too much in the client apps. Is there a good tutorial on project organization that addresses EF Code First that isn't overly complicated (ie Unity of Work)?

Model compatibility error

Setup
I have an app that uses ASP.NET Identity 2.0. The identity part shares a database with the rest of the tables needed by the application. So in one class library, I have a dbcontext that accesses the database for business data, and in another class library, I have the IdentityModel.cs, ie, the ApplicationDBContext.
Problem:
All worked fine, until I got in a muddle, trying to figure out how to work with migrations with the business data context. I ended up deleting the __MigrationHistory table and hence all the model metadata in the database for both the context.
I now get the following error:
Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations.
I deleted all migrations related to the business data, and re enabled migrations for that project. That had the effect of recreating the model metadata for the business dbcontext.
However, I can't figure out how to achieve the same for the Identity metadata.
Question:
How do I recreate the model metadata in __MigrationHistory for ASP.NET Identity 2.0?
Write below code in Global.asax.cs and try again...
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TsContext>());
I had to recreate the database and start again. I am still in the dark to the extent that I don't know if Neel's answer is the correct one for a production database. Right now, I don't have the time to properly research AspNet.Identity to find the solution to the problem. Sorry.
Prevention before Cure:
What I DO know is that the problem would not happen if I hadn't deleted the __MigrationHistory table. So the issue is one of self harming and so prevention rather than curing is the best option.
Therefore, the moral of the story is:
Moral:
Never, EVER, delete the __MigrationHistory table. Learn a bit more about it BEFORE doing any thing quite so silly, feckless, carless and downright dumb.

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.

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