I have written a very small C# program, that uses a very small SQL Server database, purely for some learning & testing purposes. The database is used in this one new pro
Working with VS 2010 and Entity Frameworks using SQL Server I've run into this more than a few times. In my case it happened when I tried to run the program and I had a query open in the Server Explorer. Once it fails I had to drop all the connections to get it to work again.
VS2010 copies the source database (an .MDF
and .LDF
file) that you work with in Server Explorer to the projects debug folder. This is the copy you are working with at runtime. When this file is copied is controled by the MDF property Copy to Output Directory
by default it is set to Copy always
. This means it will try and copy the file on a new build or run and if you have it open elsewhere it fails and then it gets hung up.
The way to see the connection is to open the SQL Server Management Console. By default VS2010 is using a user instance of SQL Server as specified in the connection string. In the case of Entity Frameworks it is in the App.Config XML.
The user instance is a separate in memory copy of SQL Server that has all the user rights assigned to the logged in user. To get to it you need to find the proper connection.
Running this query from the main instance of SQL will show all of the User Instance connections.
SELECT owning_principal_name, instance_pipe_name, heart_beat FROM sys.dm_os_child_instances
This will return something that looks like this:
|owning_principle_name | instance_pipe_name | heart_beat
--------------------------------------------------------------------------------
1 | MyServer\Admin | \\.\pipe\91B3063E-CD0F-4B\tsql\query\ | dead
--------------------------------------------------------------------------------
2 | MyServer\Rich | \\.\pipe\B04A1D3B-6268-49\tsql\query\ | alive
If you copy the instance name and use it as the server name in a new connection, running as the user associated with it you will see your data from the debug folder.
Now if you right click on the database and select Tasks >
Detach...
You will open a Detach Database
dialog check the Drop Connections
checkbox next to the database file name and click OK
.
The database will be removed from the list and you should be able to build and run you application.
try running sp_who2 to see the list of process.
FYI: you don't need to reboot your machine, worst case, restart SQL Server service
The simplest thing is go Server Explorer. Choose the problem database. Right-click and choose "Close Connection".
If it is already closed, connect and disconnect.
This is the rewritten code, using the "Using" statements. When I execute the program and click on Insert Record Into SQL File, off it goes, completes the process with myCount = 1 (though I'm not 100% sure that it is actually doing a physical Write, am I missing a command that actually "commits" the update ?!?) and re-displays the Form.
If I then click on Insert Record Into SQL File again, I get an error as follows :
SqlException was unhandled
Cannot open user default database. Login failed. Login failed for user 'MEDESKTOP\Gary'.
This is the program (I am the only user on this PC and have full Admin rights, the "State" of the database at this point is, according to Properties, Closed, so it looks like the first pass through the code did as was expected ...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace MySqlTest
{
public partial class Form1 : Form
{
int myCount;
string myDBlocation = @"Data Source=MEDESKTOP;AttachDbFilename=|DataDirectory|\mySQLtest.mdf;Integrated Security=True;User Instance=False";
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
myCount++;
MessageBox.Show("myCount = " + myCount.ToString());
//Insert Record Into SQL File
myDB_Insert();
}
private void button3_Click(object sender, EventArgs e)
{
//Read Record From SQL File
}
private void button4_Click(object sender, EventArgs e)
{
//Read All Records From SQL File
}
private void button5_Click(object sender, EventArgs e)
{
//Delete Record From SQL File
}
private void button7_Click(object sender, EventArgs e)
{
//Quit
myDB_Close();
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_Close(object sender, EventArgs e)
{
}
void myDB_Insert()
{
using (SqlConnection myDB = new SqlConnection(myDBlocation))
using (SqlCommand mySqlCmd = myDB.CreateCommand())
{
myDB.Open(); **<<< Program fails here, 2nd time through**
mySqlCmd.CommandText = "INSERT INTO Parent (ParentName) VALUES(@ParentNameValue)";
mySqlCmd.Parameters.AddWithValue("@ParentNameValue", myCount);
mySqlCmd.ExecuteNonQuery();
myDB.Close();
}
return;
}
void myDB_Close()
{
using (SqlConnection myDB = new SqlConnection(myDBlocation))
using (SqlCommand mySqlCmd = new SqlCommand())
{
myDB.Close();
}
return;
}
}
}
I don't understand why I am suddenly losing access to my own file that I am already using ?!?