I am trying to use EntityFramework 6 Migrations in conjunction with Azure Databases. I am using a SqlConnection with AccessToken to Connect to the Azure Database and Migrate.
public class MasterDbContext : DbContext
{
//...
public MasterDbContext(SqlConnection connection)
: base(connection,true)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MasterDbContext, Migrations.Configuration>(true));
}
//...
}
public async Task SeedMasterDatabaseAsync(string connectionString)
{
SqlConnection conn = new SqlConnection(connectionString)
{
AccessToken = "xyc"
};
using (var dbcontext = new MasterDbContext(conn))
{
dbcontext.Database.Initialize(false);
}
}
I am receiving the followoing exception:
Unhandled Exception: System.InvalidOperationException: This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection. ---> System.Data.SqlClient.SqlException: Login failed for user ''.
The exception message implies that the DBMigrator is not useing the SQL Connection but tries to create a new Connection from the Connectionstring.
This is my Connectionstring:
<add name="MasterDbContext" connectionString="Server=foo;Persist Security Info=True;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" providerName="System.Data.SqlClient" />
The question is, are AccessToken supported in EF6.3 Migrations in conjunction with Azure Databases? Or is this an permission Issue on master database? Any workaround if AccessToken are a mandatory requirement?
Related
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'.
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
I get the following Metadata Exception from Entity Framework when running query:
Schema specified is not valid. Errors:
error 0194: All artifacts loaded into an ItemCollection must have the
same version. Multiple versions were encountered.
Oracle.DataAccess.src.EntityFramework.Resources.EFOracleStoreSchemaDefinition.ssdl(2,28)
: error 0172: All SSDL artifacts must target the same provider. The
Provider 'System.Data.SqlClient' is different from
'System.Data.SqlClient' that was encountered earlier.
Oracle.DataAccess.src.EntityFramework.Resources.EFOracleStoreSchemaDefinition.ssdl(2,64)
: error 0169: All SSDL artifacts must target the same provider. The
ProviderManifestToken '9.2' is different from '2012' that was
encountered earlier.
This is my Entity Connection String
"metadata=res://*;provider=System.Data.SqlClient;provider connection string=\"SERVER=SERVER;DATABASE=DB;Trusted_Connection=True;\""
(It is derived from a normal connection string using this method:
private static string GetEntityConnectionString(string connectionString)
{
var sbEntity = new EntityConnectionStringBuilder();
sbEntity.Provider = "System.Data.SqlClient";
sbEntity.ProviderConnectionString = connectionString;
sbEntity.Metadata = "res://*";
return sbEntity.ToString();
}
I pass it a standard connection string: "SERVER=SERVER;DATABASE=DB;Trusted_Connection=True;"
Very strange that it thinks it's somehow Oracle related. How do I fix this?
I'm creating application, that will be able to connect to any database which user wishes. I'm trying to connect, but I'm always getting exception about connection string. My code looks like:
public string GetConnectionString(string userName, string password, string database, string server)
{
return string.Format(
#"metadata=res://*/Data.Database.csdl|res://*/Data.Database.ssdl|res://*/Data.Database.msl;provider=System.Data.SqlClient;provider connection string="data source={0};initial catalog={1};persist security info=True;user id={2};password={3};multipleactiveresultsets=True;App=EntityFramework"",
server,
database,
userName,
password);
}
and
DatabaseContext context = new DatabaseContext(GetConnectionString(UserName, Password, DatabaseName, ServerName));
What is wrong with my connection string? I just copied it from app.config file.
Answer is on this page: http://msdn.microsoft.com/en-us/library/vstudio/bb738533(v=vs.100).aspx. They are creating SqlConnectionStringBuilder and after that EntityConnectionStringBuilder which produces proper Entity Framework connection string.
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.