I try to deploy my project into Azure, and while the publishing is successful, I always get the "A network-related or instance-specific error occurred while establishing a connection to SQL Server. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)" error.
I read/watched a few tutorials about publishing an asp.net project via Visual studio, and I noticed a difference between my project and those in the tutorials:
While others had only one database in the "Settings" section of their Publish window, I have two, and I don't know why. I figured that this may be the reason I get the error.
Here's my window:
And here's one from a tutorial:
I don't really get this, because I should have only one database, like my server explorer shows:
In my web.config file there's only one connection string defined, and that's for the DefaultConnection:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-vocab_2-20130928092402;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-vocab_2-20130928092402.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
I guess my DbContext-derived VocabModel class is also relevant:
public class VocabModel : DbContext
{
public VocabModel() : base("name=DefaultConnection")
{
if (Membership.GetUser()!=null)
{this.currentuser = UserProfiles.Find((int)Membership.GetUser().ProviderUserKey);}
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<ForeignExpression> ForeignExpressions { get; set; }
public DbSet<PracticeResult> latestResults { get; set; }
}
So what's wrong? Did I make a fundamental error with Entity Framework? (this is the first time I'm using it)
Well, it was the
if (Membership.GetUser()!=null)
{this.currentuser = UserProfiles.Find((int)Membership.GetUser().ProviderUserKey);}
part in my model's constructor. I moved this code to the get method of the currentuser property (which is more logical anyway), and now it works as expected. Any explanation would still be appreciated. (Why did that part cause an additional database during publish?)
Related
Problem I'm dealing with, is weird error :
SqlException: 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: 52 - Unable to locate a Local Database Runtime installation. Verify that SQL Server Express is properly installed and that the Local Database Runtime feature is enabled.)
it happens whenever any method with db is called, like:
foo()
{
return _dbContext.data.ToList();
}
File db was created automatically based on code first approach and connection string:
<add name="Context"
connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\RestApi.Services.Context.mdf;Initial Catalog=RestApi.Services.Context;Integrated Security=True"
providerName="System.Data.SqlClient" />
I can connect with no errors to that file by VS server explorer.
On same PC I've runned several others apps with file db without any errors.
When I watch "Context" var in debbuger it seems connected to proper DB, but have error on workspaceID.
Now I'm stuck and don't have any idea how to fix it. :(
UnityConfig:
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<Context, Context>(new PerThreadLifetimeManager());
container.RegisterType<IXService, XService>();
DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
}
Context class:
public class Context : DbContext
{
public Context() : base("name=Context")
{
}
public DbSet<X> Xs{ get; set; }
public DbSet<Z> Zs{ get; set; }
public DbSet<Y> Ys{ get; set; }
}
EDIT
File Db was not the problem, I've tried with normal db connection string, and errors still occur.
I've tried many different solutions and no one works :(
now after change in UnityConfig:
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<DbContext, Context>();
container.RegisterType<IXService, XService>();
DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
}
first db read:
InvalidOperationException: The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.
next ones:
NullReferenceException: Object reference not set to an instance of an object.
EDIT2
Docker support was causing problems ;/ I'll upload solution when I find one
make sure that connectionstring data source is valid server name. if server name is valid then follow this instruction, this may help you.
Open "SQL Server Configuration Manager"
Now Click on "SQL Server Network Configuration" and Click on "Protocols for Name"
Right Click on "TCP/IP" (make sure it is Enabled) Click on Properties
Now Select "IP Addresses" Tab -and- Go to the last entry "IP All"
Enter "TCP Port" 1433.
Now Restart "SQL Server .Name." using "services.msc" (winKey + r)
I am expreimenting with asp.net mvc code first technique and want to make a new database with my code but i am not able to get access to my server management studio it gives the error
Cannot open database "Webstore.mdf" requested by the login. The login failed.
Login failed for user 'sa'.
Here is my webconfig connection string
<connectionStrings>
<add name="DBCS" connectionString="Server=HAIDER-PC;
Database=Webstore.mdf;User ID=sa; Password=123456;"
providerName="System.Data.SqlClient" />
</connectionStrings>
here is my code for DBCS class
namespace vidly.Models
{
public class DBCS: DbContext
{
public DbSet<Item> Items { get; set; }
public DbSet<Category> Categories { get; set; }
}
}
NOTE: My sa password is correct, my SQL server is on same machine, i can create the database by modifying connection in server explorer and then click "Yes" on the dialog box which says database does not exist do you want to create new?
I have set up a Code First using the following DbContext
public class MyDatabaseDbContext : DbContext
{
public MyDatabaseDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
public MyDatabaseDbContext()
: base("MyDatabase")
{
}
public DbSet<MyTable> MyTables { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
I have also set up the connection string to look at the (Local) database
<connectionStrings>
<add name="MyDatabase"
connectionString="Server=(local);Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=true"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
Also set up the initializer in Global.asax
Database.SetInitializer<MyDatabaseDbContext>(new DropCreateDatabaseAlways<MyDatabaseDbContext>());
I then run the application and call the DbContext (in my case from the controller)
var dbContext = new MyDatabaseDbContext();
var myTableResults = dbContext.MyTables.ToList();
I get the follow error message
An exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.dll but was not handled in user code
Additional information: 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: 50 - Local Database Runtime error occurred. Cannot get a local application data path. Most probably a user profile is not loaded. If LocalDB is executed under IIS, make sure that profile loading is enabled for the current user.
On Debugging and looking at the dbContext variable > Database > Connection > ConnectionString Property I see the following:
"Data Source=(localdb)\v12.0;AttachDbFilename=|DataDirectory|MyDatabase.mdf;Initial Catalog=MyDatabase;Integrated Security=True;MultipleActiveResultSets=True"
Questions
Why is it pointing to the (localDb)\v12.0 database and not my connection string?
Even so, Why is it not creating the database there anyway as this is on my dev machine?
Is there some kind of convention which I have forgotten about which I need to set.
Your connection string needs to be named MyDatabaseDb
OR
your context class needs to be named MyDatabaseContext.
Entity Framework's convention is for the context class to look for a connection string with the same name + Context. The Db in your class name is extraneous.
I wish to pass a dynamic connection string to the entity framework context. I have over 150 schemas which are identical (one per account) and I would like to select the connection as such:
ApplicationDbContext db = new ApplicationDbContext("dbName");
In theory this would be fairly easy, as I can create a connectionString and pass it as the argument for the constructor, for example:
public ApplicationDbContext(string dbName) : base(GetConnectionString(dbName))
{
}
public static string GetConnectionString(string dbName)
{
// The connectionString passed is something like:
// Server=localhost;Database={0};Uid=username;Pwd=password
var connString = ConfigurationManager
.ConnectionStrings["MyDatabase"]
.ConnectionString
.ToString();
return String.Format(connString, dbName);
}
I can connect successfully when I just pass the connection string name, but not when I generate it dynamically as below. I realize now that it's because the connection string in web.config has the providerName="MySql.Data.MySqlClient" attribute in it.
When I pass the actual connection string dynamically to the connection though, it assumes that it needs to connect to SQL Server rather than MySQL and fails due to the connection string being invalid.
The question is, how do I pass the provider name to the connection string if I am creating it dynamically?
Entity Framework 6 offers some handy subtle changes which aid in both getting MySQL working and also creating dynamic database connections.
Getting MySQL working with Entity Framework 6
First, at the date of my answering this question, the only .Net connector drivers compatible with EF6 is the MySQL .Net Connectior 6.8.1 (Beta development version) which can be found at the official MySQL website here.
After installing, reference the following files from your Visual Studio solution:
Mysql.Data.dll
Mysql.Data.Entity.EF6.dll
You will also need to copy these files somewhere where they will be accessible to the project during build time, such as the bin directory.
Next, you need to add some items to your Web.config (or App.config if on desktop based) file.
A connection string:
<connectionStrings>
<add name="mysqlCon"
connectionString="Server=localhost;Database=dbName;Uid=username;Pwd=password"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
Also add the provider, inside the <entityFramework /> and <providers /> nodes, optionally (this is an absolute must in the second part of my answer, when dealing with dynamically defined databases) you may change the <defaultConnectionFactory /> node:
<entityFramework>
<defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
</providers>
</entityFramework>
If you change the defaultConnectionFactory from the default sql server connection, don't forget to remove the <parameter> nodes which are nested in the defaultConnectionFactory node. The MysqlConnectionFactory does not take any parameters for its constructor and will fail if the parameters are still there.
At this stage, it's quite easy to connect to MySQL with Entity, you can just refer to the connectionString above by name. Note that if connecting by name, this will work even if the defaultConnectionFactory node still points at SQL Server (which it does by default).
public class ApplicationDbContext: DbContext
{
public ApplicationDbContext() : base("mysqlCon")
{
}
}
The it is just a matter of connecting normally:
ApplicationDbContext db = ApplicationDbContext();
Connecting to a dynamically selected database name
At this point it's easy to connect to a database which we can pass as a parameter, but there's a few things we need to do.
Important Note
If you have not already, you MUST change the defaultConnectionFactory in Web.config if you wish to connect to MySQL
dynamically. Since we will be passing a connection string directly to
the context constructor, it will not know which provider to use and
will turn to its default connection factory unless specified in
web.config. See above on how to do that.
You could pass a connection string manually to the context like this:
public ApplicationDbContext() : base("Server:localhost;...")
{
}
But to make it a little bit easier, we can make a small change to the connection string we made above when setting up mySQL. Just add a placeholder as shown below:
<add name="mysqlCon" connectionString="Server=localhost;Database={0};Uid=username;Pwd=password" providerName="MySql.Data.MySqlClient" />
Now we can build a helper method and change the ApplicationDbContext class as shown below:
public class ApplicationDbContext: DbContext
{
public ApplicationDbContext(string dbName) : base(GetConnectionString(dbName))
{
}
public static string GetConnectionString(string dbName)
{
// Server=localhost;Database={0};Uid=username;Pwd=password
var connString =
ConfigurationManager.ConnectionStrings["mysqlCon"].ConnectionString.ToString();
return String.Format(connString, dbName);
}
}
If you are using database migrations, the following step is important
If you are using migrations, you will find that the ApplicationDbContext will be passed to your Seed method by the framework and it will fail because it will not be passing in the parameter we put in for the database name.
Add the following class to the bottom of your context class (or anywhere really) to solve that problem.
public class MigrationsContextFactory : IDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext Create()
{
return new ApplicationDbContext("developmentdb");
}
}
Your code-first migrations and seed methods will now target the developmentdb schema in your MySQL database.
Hope this helps someone :)
It's now 2019 of course things have changed a bit but Franciso's example really helped me on this. This is the simplest solution I could find and the only one that actually worked. I did change it a bit from what he has shown. Follow this to completion you should end up with a working solution.
I had to change a few things. I am going to be very explicit in what has to be done and I am going to use my actual file names etc so that you don't have to guess about substitutions. Many examples are also short on how to make it work at the end. This example has everything you need to know.
This was built on visual studio 2015 Entityframework 6 using MySql server 8.0.16.0.
Unfortunately the MySql connectors and libraries are a complete mess. The 8.0.xx.0 connector / net and MySql.Data.Entity.EF6 and MySql.Data are completely useless.
I have installed Connector Net 6.10.7.0, MySql.Data.Entity.EF6 6.10.7.0, and MySql.Data 6.10.7.0. That works for me and I will vigorously oppose changing this.
This is for MySql but I really don't know why it could not work for any db.
Scenario
I have a multi tenant situation where I have a common db and multiple tentant databases, one per customer The customer id is kept in the common db for login purposes and authorizaton and the customer id directs which database to use. The client db's are all called myclientdb_x where x is the client number. myclientdb_1, myclientdb_2, myclientdb_35 and so on.
I need to dynamically switch to whatever clientdb_x the code is currently serving. There is a initial database client called myclient_0 which is the template for all of the other myclient_x databases.
Step1
I created a specific connection string in my Web.config for this it looks like this. It allows connections to the clientdb_0
<add name="DefaultClientConnection" providerName="MySql.Data.MySqlClient"
connectionString="server=localhost;user id=xxx;
password=xxxx; persistsecurityinfo=True;database=clientdb_0" />
Step2
I created a new entity called ClientDbUserUpdater using the wizard. The data entity is called
ClientDbUserUpdater.edmx
I told it to use "DefaultClientConnection" as the DB connection
I told it to save this new connection string in the Web.config
This created new entity connection string in the Web.config file and it will look like
<add name="myclient_0Entities" connectionString="metadata=
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.csdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.ssdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.msl;
provider=MySql.Data.MySqlClient;provider connection string="
server=localhost;user id=xxxx;password=yyyyy;
persistsecurityinfo=True;database=myclient_0"" providerName="System.Data.EntityClient" />
You might have to dig a bit because the wizard is not good about putting in \n in appropriate places.
Notice that this connection string is fundamentally the same as the initial connection string except for its name and the fact that it has
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.csdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.ssdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.msl;
The res: strings are needed by the data entity and its why you can't just send a standard connection string into the data entity.
If you try to send in the initial connection string
<add name="DefaultClientConnection" providerName="MySql.Data.MySqlClient"
connectionString="server=localhost;user id=xxx;
password=xxxx; persistsecurityinfo=True;database=clientdb_0" />
you will get an exception from
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
Step3
This new connection string is the one you need to alter. I have not tested it but I am pretty sure if change the data entity model with the wizard you will need to make this change again.
Take string:
<add name="myclient_0Entities" connectionString="metadata=
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.csdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.ssdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.msl;
provider=MySql.Data.MySqlClient;provider connection string="
server=localhost;user id=xxxx;password=yyyyy;
persistsecurityinfo=True;database=myclient_0"" providerName="System.Data.EntityClient" />
and change it to:
<add name="myclient_0Entities" connectionString="metadata=
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.csdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.ssdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.msl;
provider=MySql.Data.MySqlClient;provider connection string="
server=localhost;user id=xxxx;password=yyyyy;
persistsecurityinfo=True;database={0}"" providerName="System.Data.EntityClient" />
Notice that the only part changed is database=myclient_0 to database={0}
Step 4
The data entity created some code behind ClientDbUserUpdater.edmx. The file is called ClientDbUserUpdater.Context.cs.
The code is ...
namespace what.ever.your.namespace.is
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class client_0Entities : DbContext
{
public client_0Entities()
: base("name=client_0Entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<user> users { get; set; }
}
}
Notice that this a partial class. This means you can extend this class and add a new constructor.
Add the following class.
using System;
using System.Configuration ;
using System.Data.Entity ;
namespace what.ever.your.namespace.is
{
public partial class client_0Entities : DbContext
{
public client_0Entities(string dbName) : base(GetConnectionString(dbName))
{
}
public static string GetConnectionString(string dbName)
{
var connString = ConfigurationManager.ConnectionStrings["client_0Entities"].ConnectionString.ToString();
// obviously the next 2 lines could be done as one but creating and
// filling a string is better for debugging. You can see what happened
// by looking a conn
// return String.Format(connString, dbName);
string conn = String.Format(connString, dbName);
return conn ;
}
}
}
The class adds a new constructor which allows you to get the base connection string for the data entity model which from above looks like:
<add name="myclient_0Entities" connectionString="metadata=
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.csdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.ssdl|
res://*/Areas.Authorizations.Models.ClientDbUserUpdater.msl;
provider=MySql.Data.MySqlClient;provider connection string="
server=localhost;user id=xxxx;password=yyyyy;
persistsecurityinfo=True;database={0}"" providerName="System.Data.EntityClient" />
and modfiy it at run time to change the schema.
The String.Format() call in the new partial class swaps out the database schema name in this connection string at run time.
At this point all configuration is done.
Step 5
Now you can make it go. For better understanding of this example it is nice to know what the model looks like for this entity. It is very simple because I was just testing and trying to make it go.
Drilling down through ClientDbUserUpdater.edmx and into into ClientDbUserUpdater.tt you will find your model in modelname.cs . My model is called "user" so my file name is called user.cs
namespace what.ever.your.namespace.is
{
using System;
using System.Collections.Generic;
public partial class user
{
public int UserId { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<bool> Active { get; set; }
}
}
Now you can generally access your model like this.
client_0Entities _client_0Entities = new client_0Entities("schemaName");
and this code can be anywhere in your solution that can see class client_0Entities.
which in practice is a line similar to any of the 3 below which are connection to databases client_19, client_47 and client_68 respectively.
client_0Entities _client_0Entities = new client_0Entities("client_19");
client_0Entities _client_0Entities = new client_0Entities("client_47");
client_0Entities _client_0Entities = new client_0Entities("client_68");
the following is an actual code example that works on my system. Obviously I am going to not hard code in "client_19" but its better for demo purposes.
here is actual code with real names that works and adds a new row to the user table on database client_19
string _newSchema = "client_19"
using(client_0Entities _client_0Entities = new client_0Entities(_newSchema))
{
user _user = new user();
_user.UserId = 201;
_user.Email = "someone#someplace.com"
_user.FirstName ' "Someone";
_user.LastName = "New";
_user.Active = true;
client_0Entities.users.Add ( _user ) ;
client_0Entities.SaveChangesAsync ( ) ;
}
Hopefully this helps some people. I spent about 20 hrs looking at different solutions which simply did not work or provide enough information to complete them. As I said, finding Franciso's example allowed me to get it working.
Regards,
I'm trying to use Code First with my local instance of Sql Server 2008 R2. I've create a user 'dev' and can log in and create databases using Sql Managment Studio. The problem is I keep getting an error message when trying to create a database using DbContext in EntityFramework. Here is the error message:
"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. SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified"
The error message I checked my Sql Server and it does allow remote connections.
I've abstracted my system with the following code and get the same error:
namespace CodeFirstConsole
{
public class Program
{
static void Main(string[] args)
{
var db = new MyContext();
try { Console.WriteLine(db.Parents.Count()); }
catch (Exception) { throw; }
Console.Read();
}
}
internal class MyContext : DbContext
{
public DbSet<ParentObject> Parents { get; set; }
public DbSet<ChildObject> Children { get; set; }
public MyContext()
{
this.Database.Connection.ConnectionString =
"Data Source=.;Database=ConsoleTest;Initial Catalog=ConsoleTest;User ID=dev;Password=dev;";
}
}
internal class ParentObject
{
public int Id { get; set; }
public string PropertyOne { get; set; }
}
internal class ChildObject
{
public int Id { get; set; }
public bool PropertyOne { get; set; }
public string PropertyTwo { get; set; }
public virtual ParentObject Parent { get; set; }
}
internal class MyInitializer : DropCreateDatabaseAlways<MyContext>
{
protected override void Seed(MyContext context)
{
context.Parents.Add(new ParentObject() { PropertyOne = "hi" });
base.Seed(context);
}
}
}
I had the same error that drove me nuts for about a day. My situation was I had a large solution with a pre-existing start-up project and I was adding EF to the persistence project.
So the first step was to add the EF dependency. This created an app.config in my persistence project with the correct EF content. Then I went to Enable-Migrations and got the same error in this post. At this point I didn't think of copying the EF app.config settings to the app.config of the start-up project since I thought I'd have to play around with it before I would eventually run the app.
The problem was resolved when I changed the solution start-up project to the persistence project so I could get EF to find the correct app.config. Or I could have copied the EntityFramwework related section to the app.config of the start-up project.
Had the same error message developing on local, but it worked fine yesterday.
Turns out the wrong project in the solution was set as the StartUp Project.
So if you are also getting this message after an update-database command in the Package Manager Console, be sure to check if the correct StartUp Project is set.
For example the Web project, and not one of the helper projects.
Visual studio seems to have the habit of setting other projects as the StartUp by itself sometimes...
Try having a look here it explains a lot of the causes, since you indicated in the comments that you did explicitly specify server name and the code runs also on the same machine as sql server since from what I see the datasource just has a dot, indicating that its the same machine as the c# code program running on.
http://blogs.msdn.com/b/sql_protocols/archive/2007/05/13/sql-network-interfaces-error-26-error-locating-server-instance-specified.aspx
Had to add the EntityFramework dependency also to the startup project.
Install-Package EntityFramework
And also had to define connectionStrings to my main project App.config/Web.config.
<connectionStrings>
<add name="Database" providerName="System.Data.SqlClient" connectionString="foo.bar" />
</connectionStrings>
Here was a solution for me
Traditional SqlClient can find server instance but EF can't
In short:
Database.SetInitializer<MyContext>(
new MigrateDatabaseToLatestVersion<MyContext, Migrations.Configuration>(
useSuppliedContext: true));
Main part here is useSuppliedContext: true
I had the same problem and spent a whole day on it. Finally found #Christian's answer and now I find a much better way!
Put ConnectionString in the startup project. So you don't need to switch every time you change an entity.