Timeout when setting up Entity Framework connecting to Azure Timeout when setting up Entity Framework connecting to Azure azure azure

Timeout when setting up Entity Framework connecting to Azure


Short Answer

It takes about 120 seconds for SQL Azure to create a database. That is why you are timing out. So, increase the CommandTimeout. One way is to drop a single line of code into your DbContext constructor.

public MyContext() : base("name=MyContext"){    // three minute command timeout    this.Database.CommandTimeout = 180;}

Troubleshooting Steps

I just recreated the exception using a brand new SQL Azure server in West US. When I turned on Entity Framework logging, the output showed that the Create database statement caused the timeout. Here is the log output.

Opened connection at 9/8/2015 9:24:14 AM -07:00select cast(serverproperty('EngineEdition') as int)-- Executing at 9/8/2015 9:24:14 AM -07:00-- Completed in 40 ms with result: SqlDataReaderClosed connection at 9/8/2015 9:24:14 AM -07:00Opened connection at 9/8/2015 9:24:15 AM -07:00IF db_id(N'mvp1') IS NOT NULL SELECT 1 ELSE SELECT Count(*) FROM sys.databases WHERE [name]=N'mvp1'-- Executing at 9/8/2015 9:24:15 AM -07:00-- Completed in 306 ms with result: 1Closed connection at 9/8/2015 9:24:15 AM -07:00Opened connection at 9/8/2015 9:24:15 AM -07:00drop database [mvp1]-- Executing at 9/8/2015 9:24:15 AM -07:00-- Completed in 10635 ms with result: -1Closed connection at 9/8/2015 9:24:26 AM -07:00Opened connection at 9/8/2015 9:24:26 AM -07:00create database [mvp1]-- Executing at 9/8/2015 9:24:26 AM -07:00-- Failed in 30050 ms with error: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.Closed connection at 9/8/2015 9:24:56 AM -07:00

To troubleshoot further, I connected to the SQL Azure database with SQL Server Management Studio and ran the log output. The commands succeeded but took 1:53 to complete (just about two minutes). That exceeds the default DbContext command timeout.

The fix: increase the DbContext command timeout to exceed that duration. Bingo. It worked.

Working Console App on My Computer

packages.config

The only package is EntityFramework version 6.1.3.

<?xml version="1.0" encoding="utf-8"?><packages>  <package id="EntityFramework" version="6.1.3" targetFramework="net452" /></packages>

App.config

This config uses the interceptors section to log the generated T-SQL. That enabled me to run the logged T-SQL on SQL Server Management Studio to determine how long it takes to create the database.

<?xml version="1.0" encoding="utf-8"?><configuration>  <configSections>    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>  </configSections>  <startup>    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />  </startup>  <connectionStrings>        <add name="MyContext"          connectionString="Server=tcp:d01kzjctcf.database.windows.net,1433;Database=mvp1;User ID=mvp@d01kzjctcf;Password=3pN*iV55XmtW;Trusted_Connection=False;Encrypt=True;Connection Timeout=120;"         providerName="System.Data.SqlClient" />  </connectionStrings>  <entityFramework>    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />    <providers>      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />    </providers>    <interceptors>      <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">        <parameters>          <parameter value="C:\Temp\LogOutput.txt"/>        </parameters>      </interceptor>    </interceptors>  </entityFramework></configuration>

Program.cs

The demo simply drops and creates the database, seeds it with books, selects all the books, and outputs the number of books to the console.

using System;using System.Data.Entity;using System.Collections.Generic;using System.Data.Entity.SqlServer;public class Program{    public static void Main()    {        Database.SetInitializer<MyContext>(new MyContextInitializer());        var count = 0;        using (var context = new MyContext())        {            count = context.Books.CountAsync().Result;        }        Console.WriteLine(string.Format("There are {0} books.", count));        Console.ReadLine();    }}public class MyContextInitializer : DropCreateDatabaseAlways<MyContext>{    protected override void Seed(MyContext context)    {        context.Database.CommandTimeout = 0;        var books = new List<Book>        {            new Book() {Name = "War and Pease", Author = "Tolstoy",Price=19.95m },            new Book() {Name = "As I Lay Dying", Author = "Faulkner",Price=99.95m },            new Book() {Name = "Harry Potter 1", Author = "J.K. Rowling",Price=19.95m },            new Book() {Name = "Pro Win 8", Author = "Liberty",Price=49.95m },            new Book() {Name = "Book one", Author = "Author1",Price=10.95m },            new Book() {Name = "Book two", Author = "Author2",Price=20.95m },            new Book() {Name = "Book three", Author = "Author3",Price=30.95m }        };        books.ForEach(b => context.Books.Add(b));        context.SaveChanges();        base.Seed(context);    }}public class MyContext : DbContext{    public MyContext() : base("name=MyContext")    {        this.Database.CommandTimeout = 180;    }    public DbSet<Book> Books { get; set; }}public class Book{    public int Id { get; set; }    public string Name { get; set; }    public string Author { get; set; }    public decimal Price { get; set; }}

See Also

Set database timeout in Entity Framework

How do I view the SQL generated by the Entity Framework?

Closing Thoughts

A global CommandTimeout of three minutes is probably appropriate only for development. In production, you will probably want to decrease that or to set it only for certain specific long-running commands such as database creation.