我编写了一个非常小的C#程序,它使用了一个非常小的SQL Server数据库,纯粹是为了学习和学习。测试目的。数据库用于这个新项目,而不是其他任何地方。但是,我在运行程序无法运行的Debugs时遇到问题,因为数据库“正被另一个进程使用”。
如果我重启我的机器,它会再次运行,然后经过几次测试后我会再次遇到同样的问题。
我发现在互联网上报告了许多类似的问题,但没有找到关于如何解决这个问题的明确答案。首先,我如何找出使用我的.mdf&的“其他过程”。 .ldf文件?然后,我如何发布这些文件&是不是为了在一段时间后停止这种发生的时间而举行的?!?
我是VS2010的新手,SQL Server& C#,所以在你给我的任何回复中请说明一点!
这是我的代码,你可以看到,你无法获得更基本的东西,我当然不应该遇到这么多问题!
namespace MySqlTest
{
public partial class Form1 : Form
{
SqlConnection myDB = new SqlConnection(@"Data Source=MEDESKTOP;AttachDbFilename=|DataDirectory|\SqlTestDB.mdf;Initial Catalog=MySqlDB;Integrated Security=True");
SqlDataAdapter myDA = new SqlDataAdapter();
SqlCommand mySqlCmd = new SqlCommand();
string mySQLcmd;
int myCount;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("myDB state = " + myDB.State.ToString());
//Open SQL File
myDB.Open();
MessageBox.Show("myDB state = " + myDB.State.ToString());
}
private void button2_Click(object sender, EventArgs e)
{
myCount++;
MessageBox.Show("myCount = " + myCount.ToString());
//Insert Record Into SQL File
mySqlCmd.Connection = myDB;
mySqlCmd.CommandText = "INSERT INTO Parent(ParentName) Values(myCount)";
myDA = new SqlDataAdapter(mySqlCmd);
mySqlCmd.ExecuteNonQuery();
}
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 DQL File
}
private void button6_Click(object sender, EventArgs e)
{
MessageBox.Show("myDB state = " + myDB.State.ToString());
//Close SQL File
myDB.Close();
MessageBox.Show("myDB state = " + myDB.State.ToString());
}
private void button7_Click(object sender, EventArgs e)
{
//Quit
this.Close();
}
}
}
答案 0 :(得分:6)
最有可能的选择:
您可以通过查看Server Explorer来检查1)与TaskManager和2)。你的数据库应该显示一个小红叉,意思是'关闭'。
您应该尽快重写代码以关闭连接。使用try / finally或using(){ }
块。
答案 1 :(得分:1)
这是使用“使用”语句重写的代码。当我执行程序并单击Insert Record Into SQL File时,关闭它,用myCount = 1完成该过程(虽然我不是100%确定它实际上正在进行物理写入,但是我错过了一个实际的命令“提交”更新?!?)并重新显示表单。
如果我再次点击Insert Record Into SQL File,我会收到如下错误:
SqlException未处理
无法打开用户默认数据库。登录失败。用户登录失败 'MEDESKTOP \加里'。
这是程序(我是这台PC上唯一的用户,拥有完整的Admin权限,此时数据库的“状态”是,根据Properties,Closed,所以它看起来像是第一次通过代码按预期做了......
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;
}
}
}
我不明白为什么我突然失去了对我自己使用的文件的访问权限?!?
答案 2 :(得分:0)
尝试运行sp_who2以查看进程列表。
仅供参考:您不需要重启机器,最糟糕的情况下,重启SQL Server服务
答案 3 :(得分:0)
IIRC使用AttachDbFilename
旋转在您的进程正在使用的用户帐户下运行的SqlServr.exe
进程,与作为服务运行的SqlServer实例分开(因此停止MsSqlServer服务不会阻止此问题)。在出口脏的情况下,有时这个过程不会被清理干净。我怀疑杀死这个进程会释放db文件。
答案 4 :(得分:0)
尝试使用Microsoft的技术研究员Mark Russinovich撰写的Process Explorer。它是Windows管理员/开发人员口袋中的标准瑞士军队工具。它可以显示哪些进程持有系统资源的句柄。
安装Process Explorer后,请尝试以下操作:
搜索结果应显示一个流程/服务,其中一个资源仍由错误终止的流程保留。
答案 5 :(得分:0)
使用SQL Server使用VS 2010和实体框架我已经遇到过这种情况了。在我的情况下,它发生在我尝试运行程序时,我在服务器资源管理器中打开了一个查询。一旦失败,我不得不放弃所有连接以使其再次工作。
VS2010将您在服务器资源管理器中使用的源数据库(.MDF
和.LDF
文件)复制到项目调试文件夹。这是您在运行时使用的副本。复制此文件时,MDF属性Copy to Output Directory
默认将其设置为Copy always
。这意味着它将尝试在新的构建或运行中复制该文件,如果您在其他地方打开它会失败,然后它会挂起。
查看连接的方法是打开SQL Server管理控制台。默认情况下,VS2010使用连接字符串中指定的SQL Server用户实例。在实体框架的情况下,它位于App.Config XML中。
用户实例是SQL Server的内存副本,具有分配给登录用户的所有用户权限。要找到它,你需要找到正确的连接。
从SQL的主实例运行此查询将显示所有用户实例连接。
SELECT owning_principal_name, instance_pipe_name, heart_beat FROM sys.dm_os_child_instances
这将返回如下内容:
|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
如果您复制实例名称并将其用作新连接中的服务器名称,则以与其关联的用户身份运行,您将从调试文件夹中看到您的数据。
现在,如果您右键单击数据库并选择Tasks >
Detach...
,您将打开Detach Database
对话框,检查数据库文件名旁边的Drop Connections
复选框,然后点击{ {1}}。
数据库将从列表中删除,您应该能够构建并运行您的应用程序。
答案 6 :(得分:0)
我在http://oreilly.com/catalog/errata.csp?isbn=0636920022220
找到了这个解决方案右键单击VS数据库资源管理器中的数据库,然后单击调试会话之间的关闭连接,它对我有用。
答案 7 :(得分:0)
最简单的事情是去Server Explorer。选择问题数据库。右键单击并选择“关闭连接”。
如果已经关闭,请连接并断开连接。
答案 8 :(得分:0)
我认为已经附加了SqlTestDB.mdf。 我以前遇到过这个问题,只需转到Ms Sql server并分离数据库,然后在Visual Studio的Server Explorer中重建连接。
答案 9 :(得分:0)
您在开始时打开dbase,并且在完成时无法确定它是否已被释放。你真的在等待内存管理器对其进行排序,这取决于系统在何时释放文件时的繁忙程度。
我认为您需要将此更改为&#34;在需要时打开&#34;。
例如,我将代码放入其自己的类中的任何数据库,一旦操作完成,我就将其释放。
打开和关闭确实有开销,但我发现通过执行以下操作我可以忍受它,
您的班级中有多个入口点,一个用于单个交易,另一个用于多个交易。例如
S_UpdateSingleRecord(...)
M_UpdateManyRecords(...)
我发现在大多数应用程序中,这些都可以是静态的,因为它们本身并不存储数据,只能将数据传递给数据库或从数据库传递数据。如果我想为我的应用程序缓存一些内容,它只会失去它的静态状态。
我使用&#39;使用&#39;在S_SingleTransaction()中,因为它为我清理它。但是当我的调用函数完成时,我将多个入口点打开并关闭它。我从未遇到过单个mdf和一个应用程序的锁定问题。它将重新使用一个mdf和多个应用程序,在这些情况下,你需要使用MSSQL作为服务dbase,你会发现它在Visual Studio中设置起来很容易,然后在其他应用程序中你已经在工具栏的列表中有该数据库。