【问题标题】:How to dispose of datatables by using the 'Using' statement如何使用“Using”语句处理数据表
【发布时间】:2020-09-07 05:44:35
【问题描述】:

我正在尝试对数据表使用 using 语句,以便它在超出范围时处理掉,但在 using 范围内它说不能将数据表分配给 using 变量。下面是代码。 不使用“Using 语句”并使用 DataTable dt = null,一切正常。

using (DataTable dt = new DataTble())
{
 
 using (SqlConnection connection = new SqlConnection("DBConection"))
 {
 cmd = new SqlCommand("SPNAME", connection);
 cmd.CommandType = CommandType.StoredProcedure;
 dt = (DataTable)cmd.ExecuteNonquery(); // here it says cannot assign to dt because it is a using variable
 }      
 
 return dt;
}

【问题讨论】:

  • DataTable 甚至实现IDisposable 吗?
  • 是的,DataTable 确实实现了 IDisposable -> DataTable : MarshalByValueComponent & MarshalByValueComponent : IDisposable
  • 你不能返回DataTable,因为它会在返回给调用代码之前被释放。
  • @Enigmativity 我已得到纠正。 IIRC 曾经有一段时间记录了通过继承实现的接口,这就是为什么我首先犯了这个错误。

标签: c# asp.net datatable using


【解决方案1】:

您应该记住,在 using 块中,对象是只读的,不能修改或重新分配。 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

【讨论】:

  • 虽然这确实有助于理解 OP 看到的错误,但它并不能解决所提出的实际问题。
【解决方案2】:

用于填充DataTable 的代码对我来说似乎是错误的,因为ExecuteNonQuery() 返回一个int,因此无论如何它都不能转换为DataTable

我这样做的方法是使用SqlDataAdapter 来填充表格。

这是编译的代码 - 但不要使用它,因为这不起作用

public DataTable UsingDataTable()
{
    using (SqlConnection connection = new SqlConnection("DBConection"))
    {
        using (SqlCommand cmd = new SqlCommand("SPNAME", connection))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                using (DataTable dt = new DataTable())
                {
                    da.Fill(dt);
                    return dt;
                }
            }
        }
    }
}

您不能在返回的同时返回您正在处理的DataTable。调用代码需要能够使用它它被释放之前。

因此,这样做的方法是将使用DataTable 的代码注入到方法中,以便它可以在返回之前执行。试试这个:

public void UsingDataTable(Action<DataTable> action)
{
    using (SqlConnection connection = new SqlConnection("DBConection"))
    {
        using (SqlCommand cmd = new SqlCommand("SPNAME", connection))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            using (SqlDataAdapter a = new SqlDataAdapter(cmd))
            {
                using (DataTable dt = new DataTable())
                {
                    a.Fill(dt);
                    action(dt);
                }
            }
        }
    }
}

现在你可以这样称呼它:

UsingDataTable(dt => Console.WriteLine(dt.Rows[0][0].ToString()));

【讨论】:

    【解决方案3】:

    没有必要在数据表、数据集上实现 using 语句。这是因为数据表、数据集在其构造函数中抑制了终结。在数据表、数据集上实现 using 语句并没有真正的好处。

    【讨论】:

    • 请解释一下。 “在构造函数中抑制终结”与“不需要实现 using 语句”有什么关系?
    【解决方案4】:

    正如 cmets 所说,您只能在实现 IDisposibleclass 上使用 using 语句,而 Datatable 不会这样做。但是,您可以使用自己的dispose() 方法来处理DataTable。只是为了说得非常清楚,这也不是必需的,因为 DataTable 没有任何非托管资源

    详情请查看this 答案。

    【讨论】:

    • 是的,DataTable 可以 -> DataTable : MarshalByValueComponent & MarshalByValueComponent : IDisposable
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    相关资源
    最近更新 更多