entity framework looking at wrong database - entity-framework

VS2013 WebAPI 2.x with Repository has suddenly begin to look for data migrations to happen on a database instance other than the one it has been working with for the past 3 months - EF version 6
I have SQL Server 2012 (v11.0.2218.0) as ron-hp\localdb - this has accepted 12 migrations with add-migration/update-database commands for 3 months
As of yesterday: going to update-database yields message that
PM> update-database -verbose
Using StartUp project 'PartyPoochesClient'.
Using NuGet project 'PartyPooches.Repository'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'PartyPooches.Repository.Entities.PartyPoochesContext' (***DataSource: (localdb)\v12.0,*** Provider: System.Data.SqlClient, Origin: Convention).
I have never had an instance of v12.0 and only as of yesterday's migration / update-database attempt PM is expecting to see a (localdb)\v12.0 to accept the update. Any code search entire solution for a (localdb)\v12.0 yields nothing. As expected it times out not able to locate such an instance with SQL Server error 50, the DB, which the project created with CodeFirst, has almost 12 Migration updates to the ron-hp\localdb instance without issue.
The code:
internal sealed class Configuration : DbMigrationsConfiguration<PartyPooches.Repository.Entities.PartyPoochesContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
ContextKey = "PartyPooches.Repository.Entities.PartyPoochesContext";
}
protected override void Seed(PartyPooches.Repository.Entities.PartyPoochesContext context)
The config:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=ron-hp\localdb;Initial Catalog=PartyPooches.Repository.PartyPoochesContext; user=xxxxx;password=xxxxx; MultipleActiveResultSets=True;App=EntityFramework"/>
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
</providers>
</entityFramework>
The DbContext
public class PartyPoochesContext : DbContext, IDisposable
{
public DbSet<Dog> Dogs { get; set; }
public DbSet<Handler> Handlers { get; set; }
public DbSet<Skill> Skills { get; set; }
public DbSet<DogType> DogTypes { get; set; }
public DbSet<Schedule> Schedules { get; set; }
public DbSet<Appointment> Appointments { get; set; }
public DbSet<PaymentType> PaymentTypes { get; set; }
public DbSet<Customer> Customers { get; set; }
The settings above have seen this SQL Server 2012 instance shown for 3 months.
No changes made to settings, but a recent entity change change has been implemented for a minor database update which is now looking to a non-existence instance of SQL Server. Flawless for 3 months until yesterday. Unable to locate any internet-based information dealing with this. Acts like some NuGet package slipped something in but not certain of that.

The key to the source of your issue is here: Origin: Convention. the <parameter value="DataSource=..." for Entity Framework is not actually the project's database connection string. It is the parameter being supplied to your application's ConnectionFactory when the app creates a new DbContext. However, any other connections outside Entity Framework when the app is running, or Entity Framework itself when the app is not running (for example, migrations) expect a traditional ConnectionString key in the web.config.
When you attempt to perform an update-database and there is no ConnectionString value present, Entity Framework uses convention to decide upon a connection string to use. This convention is based on many factors, including the version of software installed on your PC. If you only have SQL LocalDb 2012 installed on your machine (the standard with earlier releases of Visual Studio 2013) then the actual localdb path would be (localdb)\v11.0 by default convention. This actually stores your database in the folder %localappdata%\Microsoft\Microsoft SQL Server Local DB\Instances\v11.0 on your disk drive.
If any application on your machine updates your system to SQL LocalDb 2014, the convention changes to (localdb)\v12.0, and new databases are assumed to be put in %localappdata%\Microsoft\Microsoft SQL Server Local DB\Instances\v12.0.
Ultimately, you should provide a more complete DataSource value than localdb, using the specific path you wish to use, (localDb)\v11.0. You also should provide a <ConnectionString> value in your web.config to match your Entity Framework <Parameters> key, to ensure that you are always guaranteed to target the same database in every instance.
Also note, that instead of using the DefaultConnectionFactory, you could instead pass the name of the <ConnectionString> key to the constructor of your DbContext.

Related

How to run database test in a Visual Studio Team Services build

I'm using Entity Framework Code First migrations (with Sql Server). For my tests, I create a test database for each execution (deleting it if exists):
// Is called once before any test is run.
[SetUpFixture]
public class Setup
{
[SetUp]
public void Init()
{
Database.SetInitializer(new TestDatabaseInitializer());
}
// ...
}
public class TestDatabaseInitializer : DropCreateDatabaseAlways<MyDbContext>
{
MyDbContext _context;
public override void InitializeDatabase(MyDbContext context)
{
_context = context;
if (context.Database.Exists())
{
// Remove database...
}
base.InitializeDatabase(context);
}
// ..
}
And the connection string for my test:
<connectionStrings>
<add name="TaskRequirementsDb" connectionString="Data Source=(localdb)\v12.0; Initial Catalog=db_test; Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
This works fine in my dev enviroment. So far no problem.
Now, I have a build in VSTS where I want to run integrated tests with a database. Is it possible? I read it is, because VSTS build servers come with MSSQL Server 2012 and MSSQL Server 2014 preinstalled (I'm using Hosted agent).
The problem is, what connection string should I use?
Note: I have already read this question:
Database integration tests in Visual Studio Online
But I don't know how apply this solution to my problem.
Edit
I've added a command line step (before running tests task) to create a localDb instance:
"%ProgramFiles%\Microsoft SQL Server\120\Tools\Binn\SqlLocalDB.exe" create "v12.0" 12.0 -s
It is executed properly:
[command]"%ProgramFiles%\Microsoft SQL Server\120\Tools\Binn\SqlLocalDB.exe" create "v12.0" 12.0 -s
LocalDB instance "v12.0" created with version 12.0.2000.8.
LocalDB instance "v12.0" started.
But the result is the same. I'm getting the following error when tests are executed:
[error] System.Data.SqlClient.SqlException: CREATE DATABASE permission denied in database 'master'.

Entity Framework code first - update database can't find .mdf in project

I am creating a small app with EF code first and I want to call the update database command from the package manager console and target the database in my app.config which is a local .mdf.
I have this connection string in my app.config
<connectionStrings>
<add name="EventsConnectionString"
connectionString="Data Source=(localdb)\v11.0;Database=EventsApp;Trusted_Connection=Yes;" />
</connectionStrings>
RegistrantContext class with connection string in constructor
using System.Data.Entity;
using EventsApp.Entities;
namespace EventsApp.Contexts.DataContexts
{
public class RegistrantDb :DbContext
{
public RegistrantDb()
: base("EventsConnectionString")
{
}
public DbSet<Registrant> Registrants { get; set; }
}
}
My file structure
And the command to update the database:
Update-Database -ConfigurationTypeName EventsApp.Contexts.DataContexts.RegistrantMigrations.Configuration -verbose
Error message
Error Number:-1,State:0,Class:20
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
I believe my settings are wrong so it can't find Events.mdf. Does anyone know what I need to change?
You should always check if you use the correct project to apply updates to (either select the correct project from the "Default Project" dropdown at the top of the package manager console or you can add -ProjectName to your Update-Database command:
Update-Database -ProjectName EventsApp.Contexts -YourOtherOptions

Migrations is enabled for context 'ApplicationDbContext' but the database does not ex

I`m trying to extend my UserIdentity, using code first migration(EF 6.0.0.0). Actually it is my first try of Code First Migration.
public class ApplicationUser : IdentityUser
{
public string NameOfUser { get; set; }
}
Add-Migration "NameOfUser" - OK
Update-Database - OK
Field in db created and marked as "allow NULL"
But when i using any action in AccountController my app throw the Error
Migrations is enabled for context 'ApplicationDbContext' but the database does not exist or contains no mapped tables. Use Migrations to create the database and its tables, for example by running the 'Update-Database' command from the Package Manager Console.
How can i resolve this prob?

How to create and connect to a test database with Entity Framework

I have a Web API project accessing a database file in its App_Data folder. The database is created using EF Migrations.
I have some integration tests to confirm data structures and queries. They just create a Web API controller and use it to perform queries. My Test Project has an App.config file, which currently has an absolute path to the *.mdf database file (in the web api project).
This is a problem because a) I am doing my tests on the application database, and b) I have an absolute path in my App.config file.
I would like to create a test database in the test project.
Is there some way I can get Migrations to create another database (with a different Seed method) in the Test Project?
In the Web Api project's Web.config connection string we use |DataDirectory| to specify the location of the database. Is there an equivalent in a test project's App.config?
Failing all that, is there some way I can point the test project's connection string to the application db without using an absolute path?
My solution is to have a static DbManager class that does a Setup(), which I will run from the [ClassInitialize] method of the database testing classes. Setup()will:
Change the connection string according to the current AppDomain.CurrentDomain.BaseDirectory (so no longer an absolute path in App.config).
Use other AppSettings from App.config to determine which database to use, which test data set to use, and whether or not to drop and recreate the database.
Some code:
public static class DbManager
{
private static string ErrorMsg { get; set; }
private static ApplicationDbContext _db;
private static readonly Random Rdm = new Random();
public static void SetupDb()
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
bool refreshDb = Convert.ToBoolean(ConfigurationManager.AppSettings["RefreshDbInTestClassInitialization"]);
string dataSet = ConfigurationManager.AppSettings["DataSetToAddForEachTestClass"];
string dbName = ConfigurationManager.AppSettings["testDatabaseName"];
var connectionStr = config.ConnectionStrings
.ConnectionStrings["DefaultConnection"].ConnectionString
.Replace("{dbPath}", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, (dbName + ".mdf")))
.Replace("{dbName}", dbName);
config.AppSettings.SectionInformation.ForceSave = true;
config.ConnectionStrings.ConnectionStrings["DefaultConnection"].ConnectionString = connectionStr;
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
if (refreshDb)
{
Database.Delete(connectionStr);
AddDataSet(dataSet, true);
}
}
// AddDataSet() creates a DbContext object and generates test data.
}
So the connection string in App.config looks like this:
connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename={dbPath};Initial Catalog={dbName};Integrated Security=True"
Then App.config AppSettings section has these extra key value pairs:
<add key ="RefreshDbInTestClassInitialization" value ="true"/>
<add key="DataSetToAddForEachTestClass" value="Large"/> <!--Possible values: Large, Small-->
<add key="testDatabaseName" value="testDb"/>

Cannot drop database because it is currently in use - EF code-first

In my configuration I have this:
public sealed class Configuration : DbMigrationsConfiguration<App.Repository.NogginatorDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(AppDbContext context)
{
SqlConnection.ClearAllPools();
//context.Database.CreateIfNotExists();
System.Data.Entity.Database.SetInitializer(new DropCreateDatabaseAlways<AppDbContext>());
if (!WebMatrix.WebData.WebSecurity.Initialized)
{
WebSecurity.InitializeDatabaseConnection("TestConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
}
}
This is used for a test db that should drop and recreate every time. Though when I hit "update-database" from the package manager console, even if the database is deleted manually prior to running, I get:
Cannot drop database "Nogginator.Test" because it is currently in use.
My connection string:
<add name="TestConnection"
providerName="System.Data.SqlClient"
connectionString="Data Source=.\;Initial Catalog=App.Test;Trusted_Connection=True;MultipleActiveResultSets=True;" />
Why would this be happening?
If you were recently debugging your web application, ensure that the IIS Express isn't still running and that there are no w3wp.exe processes associated with IIS Express. This process may still be holding on to a database connection.