DbConnection with Unity and Entity Framework on file database - c#

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)

Related

Entity Framework Connection String "The Server was not found"

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.

Using both Entity Framework and SqlConnection?

Background
I'm working on a project which contains both legacy code and Entity Framework code. I was advised to use a specific dataservice method to operate on a record from the database. The record was retrieved via Entity Framework, and I passed the PK into the dataservice function to perform the operation.
Preconditions for success and failure
If the network was up, both DB calls (entity and SQL) would succeed. If the network went down, then came back up and this code was executed, then it would retrieve the locked records with entity framework but then fail with the SqlException below.
This got me thinking, what is going on here that might cause the SqlConnection to fail despite EF being able to make the connection.
Code Samples
A code sample follows:
public void HandleNetworkBecomesAvailable() {
_entityFrameworkDataService.ReleaseRecords();
}
EntityFrameworkDataService.cs
public void ReleaseRecords()
{
using (var context = new Entities()) // using EntityConnection
{
var records = context.Records.Where(
record => record.IsLocked).ToList();
foreach (var record in records)
{
_sqlConnectionDataService.UnlockRecord(record.ID);
}
}
}
SqlConnectionDataService.cs
public void UnlockRecord(int recordId)
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Sqlconnection"].ConnectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = #"UPDATE [Records] SET [IsLocked] = 0";
//etc
command.ExecuteNonQuery();
}
}
}
App.config
<add name="EntityConnection" connectionString="metadata=res://*/FooDatabase.csdl|res://*/FooDatabase.ssdl|res://*/FooDatabase.msl;provider=System.Data.SqlClient;provider connection string="data source=RemoteServer;initial catalog=FooDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
<add name="SqlConnection" connectionString="Server=RemoteServer;Database=FooDatabase;Trusted_Connection=True" />
Now, after discussing with my coworkers, I ended up moving the logic into the entity framework dataservice and doing the work there. But I'm still not quite sure why the connection kept failing.
Edit: The actual error is:
An exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.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: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
Inner Exception:
The network path was not found
But Entity Framework is using the same network path, as can be seen in the two connection strings in the App.config.
Could you be benefiting from entity framework's new resiliency, where it retries transparently? If the error is intermittent, you won't even know it retried, whereas ADO.net is letting you know it fails as soon as it fails. Just checking...

How can I check the connectivity in a Linq2Sql app so it doesn't freeze if it fails?

So I've been using LINQ to SQL (dbml) for my C# projects for a bit now as it makes integrating SQL pretty easy for me.. the only thing is everything is so automated that I don't know how to actually edit things.
Using LINQ to SQL makes it so that it automatically connects to the database IP with user and pw in the connection string it creates in the config file but say the database isn't up.. or i want to change IPs.. the app freezes on start up.
How can I test for connectivity before having it automatically connect? I can't seem to find where in the code it does this exactly.
Your settings for the Entity, I am rusty on Linq to SQL but think it is similar, are in the App.Config on the project where you CREATED you Linq to SQL model. They are similar to this(using Entity Model):
< connectionStrings>
< add name="Example" connectionString="metadata=res://*/ExampleDB.csdl|res://*/ExampleDB.ssdl|res://*/ExampleDB.msl;provider=System.Data.SqlClient;provider connection string="data source=ACTUALSERVER;initial catalog=ACTUALDATABASE;persist security info=True;user id=(SET USER HERE);password=(SET PASSWORD HERE);multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
< /connectionStrings>
The important part for connection is the connection string though:
"data source=ACTUALSERVER;initial catalog=ACTUALDATABASE;persist security info=True;user id=(SET USER HERE);password=(SET PASSWORD HERE);
You can try to alter this to different connection strings if you want, and keeping the metadata the same. For differenent environments like "Dev", "QA", "UAT", "PROD" etc... And then copy and paste the connection block starting with the '< add name="' and till the end portion of 'providerName='(thing)' />. Then just alter the connection string and give it a different name. Then you could have the calling code use a different context or connection like:
using(MyContext context = new MyContext())
{
context.Connection = (new connection)
(your data return method)
}
You may be able to do this directly in the constructor of your context(MyContext). Cannot recall. Generally I usually set up multiple configs "DEV", "QA", "UAT", "PROD" and have them build for different environments for a service. You can build a connection string manually but dynamic connection strings can be a pain as you as a developer now need to ensure a few things:
The model of a Dev environment EXACTLY matches another with it's objects in your model. If not goodbye code return.
If you are invoking a set user that you are ensuring that your user has rights on certain environments
That you are not putting the integrity of your code at risk by showing too much publicly for user settings.
(All assuming you're using Sql Server)
Expanding on djangojazz's answer.
public void TestDbConnection()
{
Task.Factory.StartNew(() =>
{
bool isAvailable = false;
using(MyContext context = new MyContext())
{
var connection = ((IObjectContext)context).Connection as SqlConnection;
try
{
connection.Open();
isAvailble = true;
}
catch (Exception ex)
{
}
}
TestDbConnectionComplete(isAvailable);
});
}
public void TestDbConnectionComplete(bool isAvailable)
{
}

Unwanted database during Azure deploy

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?)

Entity Framework Code First Error "Error Locating Server/Instance Specified"

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.

Categories