Precompiling (creating a mapping?) EF DbContext for faster debugging - asp.net

It takes a while (3 minutes+) to 'create/compile' my DbContext. The web server starts in about 5 seconds, but when I do the first query to my database, Entity Framework has to 'build/create/compile' the database in memory or something, I think? The next requests are almost instant. This was a Database First creation of the DbContext, the database already exists in MSSQL and has data. The DbContext contains about 500 DbSet's with relations.
Is there a way to speed this up by doing the 'creation(mapping?)' of my Entity Framework's DbContext before running the web server, create the file/mappings it needs, so the first request is fast too?
EDIT1:
I've tried the Power Tools, but they give me an error that the DbContext has no constructor that can be used, while it has a normal constructor
public DbContext() : base() {}
Any other things I could try?

The Entity Framework documentation describes how to generate views using EF Power Tool here.
Once you have in stalled EF Power Tools you have to:
Right click on the class containing your DbContext or on your .edmx file
Select "Generate Views"
This will generate the class containing the pre-computed mapping, which will automatically load on startup. If you change your database and don't regenerate the views EF will throw an exception.
Whether it will work for EF7 though, who knows...

Related

How to get current transaction from the dbcontext

In Entity Framework 6, under the DbContext class you can get to current transaction by context.Database.CurrentTransaction. However this API doesn't seem like available in EF.Core. How can I retrieve current transaction object from a dbcontext in EF.Core?
EF Core still lacks many EF6 features, but (slowly) is catching up.
In that regard, I can't say for earlier versions, but in the latest (so far ) v1.1.0 the DbContext.Database CurrentTransaction property is there, so you can use the same code as in EF6 to access it.

Can you create a database without migrations in EF5?

I am following the offical asp.net "Getting started with EF 5 using MVC 4". In that tutorial, the database is created when the migrations are performed(in my understanding). When I was looking at the EF 5 with Mvc 5 tutorial they didn't use migrations to create a database. They use database initializer. So, I was wondering could create a database for your project without using migrations in EF 5? Also, what would the difference be with both these approaches?
Code first Migrations and using Package Manager Console Commands to do upgrades can get a bit confusing at first.
You can use the initializer to CreateDatabaseIfNotExists , DropCreateIfModelChanges, DropCreateDatabaseAlways and to MigrateDatabaseToLatestVersion
See the interface IDatabaseInitializer<TContext>.
CreateDatabaseIfNotExists // is the Default initializer.
So this is why it appears EF just does things for you sometimes.
So the answer is "YES you can "Create a Database without Migrations"
But the difference is not obvious and if you would do that long term is another question.
If you are using migrations. It would Update the Db to match the code first model.
If there is NO database, then that means creating the database.
So Thats why Automated migrations and CreateDB look confusing since they can result in same outcome sometimes. But technically they are different.
So generally it is sufficient to use code first automatic "migrations" only.
Migrations can be either Automatic or "managed".
The managed migrations approach invovles generating code , tweaking the code and running PM commandlet or POwershell command to actually perform the migration.
With Automated migrations you just need set the intitializer and Access the DBContext.
There are 2 parts to the process.
a) The DB Initializer step.
do this immediately before instantiating YourDBContext.
//eg
// DONT TOUCH MY DB or i break your back!
Database.SetInitializer(new ContextInitializerNone<YourDbContext>()); // Do Nothing,
// OR
// yes migrate my db to match my code please.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourDbContext, YourMigrationConfiguration>()); // Set to migration is requested, see config class below
The Confirguration class specified when using Migration initializer looks like this
public class YourMigrationConfiguration<TContext> : DbMigrationsConfiguration<TContext>
where TContext : DbContext{
protected YourMigrationConfiguration() {
AutomaticMigrationsEnabled = true; // run it when needed. Do not wait for my PM Command
AutomaticMigrationDataLossAllowed = true; // if the new db look means dropping tables or columns go ahead and kill my data. So use this option with caution.
}
then just trigger the migration in code when required.
Context.Database.Initialize(true); // i place this inside a method on my UoW class
Code first Db initialization strategies.
Code first migrations recommended reading
Managed Migrations
There are many articles on the web on this topic.

EF Code First DB gets dropped if used in different projects

I have an application which uses Entity Framework Code First models.
The structure of the project looks like this
Application.Models POCO objects
Application.EF EF Data Context and repositories
Application.Web.MVC The web application (the designer)
The context initializer looks like this:
public class DBContextInitializer : DropCreateDatabaseIfModelChanges<DBContext>
{
protected override void Seed(DBContext context)
{
}
}
Now, i have another API Application which gets the data from database as API calls. The project looks like this:
Application.Api.MVC The MVC4 API Project, containing DTO objects
Application.Models Same project
Application.EF Same project
Even if i don't change the POCO classes (inside Application.Models project), Entity Framework detects that the Metadata has changed, and tries to drop and re-create the database. If it does it, when i run the Designer Application (Application.Web.MVC), it drops it again, and so on.
I don't know why is it doing this. I am not changing the models.
Please ignore the question, it is all working. I was pointing to a different database.
Also, this was a good reason to learn about EF Migrations

Entity Framework 5 Code-First dropping/recreating database when app is restarted

I'm experimenting with the latest EF 5 CF (in VS2010, not VS2012). I'm generally following the MSDN EF 5.0 Quickstart: Creating a Model with Code First...
Rather than using a console app, my DbContext is in a Windows Service, which will eventually expose various data service methods by hosting a WCF Service (the client will be WPF MVVM)
In the OnStart of the Windows Service, I invoke SetInitializer, and then do a simple query to trigger initialization:
// Start the Windows service.
protected override void OnStart(string[] args)
{
Database.SetInitializer<MediaLibraryContext>(new MediaLibraryContextInitializer());
using (var context = new MediaLibraryContext())
{
var firstMedia = (from m in context.Medias select m).FirstOrDefault();
}
...
And EF CF creates the database from the model and seeds it, as expected.
But when I stop/restart the Service, EF appears to delete the database and recreate it (or perhaps it's just dropping the tables and recreating them?). All post-initialization changes I've made to the database are gone, and only the "seed" data is present.
I've worked with EF 4.1 and 4.3, but I've never seen this behavior. Any ideas where to look???
DadCat
EDIT: I found the problem just after posting this... the Quick start code has the database initialization strategy set to DropCreateDatabaseAlways.
That's what I get for copy/pasting code without carefully looking at it!
DC
I found the problem just after posting this... the Quick start code has the database initialization strategy set to DropCreateDatabaseAlways.

EF 4.1 Code First and Existing Database and .NET Membership

I have a database called ApplicationName_Development running on SQL Server 2008 R2 Developer edition on my development box.
I added .NET membership tables to the database with no problem. When I tried to get Code First working I received the following error message:
The server encountered an error
processing the request. The exception
message is "Model compatibility cannot
be checked because the database does
not contain model metadata. Ensure
that IncludeMetadataConvention has
been added to the DbModelBuilder
conventions.
After some googling, I discovered that I had to delete the database and let EF create the database. That's fine but I lost all my .NET membership tables. I can go back in and add the membership tables again but if my model changes and EF needs to recreate the database then I have to add the membership tables in again.
How do I get around this?
This is how code-first work. Main idea of code first is that you do not touch your database because it is responsibility of the model to create the database. If you want to customize your database you must create custom IDatabaseInitializer and add your custom SQL.
public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
protected override void Seed(MyContext context)
{
// Here run your custom SQL commands
context.Database.ExecuteSqlCommand("CREATE TABLE ....");
}
}
Now you only need setup your cutom intializer on the startup of your application:
Database.SetInitializer<MyContext>(new MyDbInitializer());
If you don't want to do it this way you must manually maintain your database and set initializer to null.
Found a easier workaround here. I hope this helps.
http://www.paragm.com/ef-v4-1-code-first-and-asp-net-membership-service/
Another option could be to use the System.Web.Management namespace. I've had great success with the code below:
string connectionString = ConfigurationManager.ConnectionStrings["MyDatabaseContext"].ConnectionString;
string database = "MyDatabaseName";
SqlServices.Install(database, SqlFeatures.All, connectionString);
It will just create the database and after that you can add users with the standard membership API.
Here's another possibility.
If you look at the MvcMusicStore sample - there's a SampleData class that is responsible for seeding the database on a rebuild. The SampleData class inherits from DropCreateDatabaseIfModelChanges, and overrides the Seed method. This class is passed to the Database.SetInitializer in the Application_Start method in global.asax.
I was getting the same error as you until I changed the parent class of SampleData to CreateDatabaseIfNotExist.
Then you can override the Seed method to insert any data you desire at startup, without it blowing away the database.
While you are developing, create 2 databases and two connection strings. One for SqlMembership (using aspnet_regsql) and one for your EF Application. If you would like to merge them into a single DB in production, just change the connection string in web.config.release to be the same. Then, EF model changes will just drop your apps db and not your membership DB.
By treating your authentication component separately, you will naturally decouple your authentication system from your application system. Then, if you wish to change membership providers, you will be better setup.
As the system grows, you will likely need to support non-pure models without EF code first, so this is a good template for going down that path.
I found the easiest way without playing with anything else was the following.
I ran the application first time with DropAndRecreatedatabase always in the Initilizer.
This created my database for the first time.
Following this I changed this to DropCreateDatabaseIfModelChanges.

Resources