我正在经历一个问题“不属于WCF web服务中的表”。这是因为另一个线程用其他模式覆盖了datatable。我通过实现日志进行了调试,发现整个模式和数据被另一个数据库调用更改了,该调用是在第一个调用之后依次调用的。当第一个datatable对象的内存实例未声明为静态时,它如何被第二个datatable对象覆盖,这让我感到非常惊讶。我使用了线程锁定,但不幸的是,它无法工作。我不确定这是MS,但可能有一个解决方案,我目前还不知道。
下面是方法调用的顺序:首先,我用用户身份验证的用户凭据填充datatable,这个datatable只有三列和一行。其次,我用处理请求所需的其他数据填充另一个datatable,然后再填充一个处理请求所需的表。
有时,在第一个datatable上弹出“”不属于该表的错误,有时它出现在第二个datatable上。当我记录表模式时,它与第二个表模式完全不同。
下面是第一个datatable的代码:
public UserCredentials GetUserCredentials(string userName)
{
try
{
UserCredentials userCredentials = null;
using (SqlCommand cmd = new SqlCommand())
{
DataTable dt = new DataTable("User");
cmd.CommandText = "dbo.[stored procedure]";
cmd.Connection = this.connection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@UserName", userName);
using (SqlDataAdapter sda = new SqlDataAdapter())
{
sda.SelectCommand = cmd;
sda.Fill(dt);
}
if (dt != null && dt.Rows.Count > 0)
{
userCredentials = new UserCredentials();
userCredentials.UserName = userName;
userCredentials.SiteID = dt.Rows[0]["SiteID"].ToString();
**userCredentials.Password = dt.Rows[0]["Passphrase"].ToString();**
}
}
return userCredentials;
}
catch (Exception ex)
{
throw ex;
}
}第二个数据表:
public GatewayProfile GetGatewayProfile(string siteID)
{
Int64 gatewayID = 0;
string submitterID = "";
GatewayProfile gatewayProfile = null;
try
{
this.OpenConnection();
DataTable dtGateway = new DataTable("GTDetails");
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "dbo.[stored procedure]";
cmd.Connection = this.connection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@SiteID", siteID);
using (SqlDataAdapter sda = new SqlDataAdapter())
{
sda.SelectCommand = cmd;
sda.Fill(dtGateway);
}
}
if (dtGateway != null && dtGateway.Rows.Count > 0)
{
gatewayProfile = new GatewayProfile();
if (Convert.ToBoolean(dtGateway.Rows[0]["IsDefault"]) == false)
{
gatewayID = Convert.ToInt64(dtGateway.Rows[0]["GatewayID"]);
submitterID = dtGateway.Rows[0]["SubmitterID"].ToString();
}
DataTable dtRoute = new DataTable("RTDetails");
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "dbo.[stored procedure]";
cmd.Connection = this.connection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@GatewayID", gatewayID);
cmd.Parameters.AddWithValue("@SubmitterID", submitterID);
using (SqlDataAdapter sda = new SqlDataAdapter())
{
sda.SelectCommand = cmd;
sda.Fill(dtRoute);
}
}
if (dtRoute != null && dtRoute.Rows.Count > 0)
{
gatewayProfile.GatewayID = Convert.ToInt64(dtRoute.Rows[0]["GatewayID"]);
gatewayProfile.SubmitterID = dtRoute.Rows[0]["SubmitterID"].ToString().Trim();
**gatewayProfile.ReceiverID = dtRoute.Rows[0]["ReceiverID"].ToString().Trim();**
gatewayProfile.AuthInfo = ReplaceDBNull(dtRoute.Rows[0]["AuthInfo"], "").Trim();
gatewayProfile.SecurityInfo = ReplaceDBNull(dtRoute.Rows[0]["SecurityInfo"], "").Trim();
}
}
return gatewayProfile;
}
catch (Exception ex)
{
throw ex;
}
finally
{
this.CloseConnection();
}
}第三数据表
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "dbo.[stored procedure]";
cmd.Connection = this.connection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@param1", param1);
cmd.Parameters.AddWithValue("@param2", param2);
cmd.Parameters.AddWithValue("@param3", param3);
cmd.Parameters.AddWithValue("@param4", param4);
using (SqlDataAdapter sda = new SqlDataAdapter())
{
sda.SelectCommand = cmd;
sda.Fill(dt);
}
}如果有人帮我解决这个问题,请提前谢谢。
发布于 2014-09-23 07:12:28
经过几周的努力,我发现了这个问题,并在这里找到了SqlDataAdapter http://msdn.microsoft.com/en-us/library/ms810286.aspx的详细文档,说明了它是如何工作的,但是在某种程度上,SqlDataAdapter对于局部变量和实例变量的行为是一样的,这些变量不应该是相同的,因为这两种类型的变量都有各自独立的内存空间,并且永远不能被覆盖。我也发布了一个错误到MS,但到目前为止没有得到任何答复。
这个问题有两个解决办法。
当您想要管理并发和多线程时,必须为DataTableMappings和DataColumnMappings定义SqlDataAdapter。
2-对每个调用使用带有单独连接的SqlDataReader
发布于 2014-09-17 07:55:40
如果dt是在线程之间共享的,那么您必须同步对它的访问,很可能使用Monitor或lock。
如果没有共享,请尝试为每个DataTable使用三个不同的。
您的代码片段和描述不足以可视化整个场景。
https://stackoverflow.com/questions/25872528
复制相似问题