【问题标题】:return type of SqlDataReader methodSqlDataReader 方法的返回类型
【发布时间】:2013-07-27 03:36:58
【问题描述】:

我在一个类中有一个方法,它包含 SqlDataReader(它连接到数据库表并检索多行)。 稍后我想将 SqlDataReader 拥有的每条记录分配给 asp 标签。但我不知道方法的返回类型应该是什么,所以我可以从中提取值,以及如何在代码隐藏文件中执行此操作。 这是代码;

 public (???) displayCustoemrhShipOrder()
    {
        string htmlStr = string.Empty;                   
        string sConnectionString = ConfigurationManager.ConnectionStrings["LGDB"].ToString();
        SqlConnection SqlCOn = new SqlConnection(sConnectionString);
        SqlCommand SqlCmd = new SqlCommand();
        SqlCmd.Connection = SqlCOn;
        SqlCmd.CommandText = "displayCustomerShipOrder";
        SqlCmd.CommandType = CommandType.StoredProcedure;
        SqlCOn.Open();
        SqlCmd.Parameters.AddWithValue("ShipOrderID",shipOrderID);
        SqlDataReader reader = SqlCmd.ExecuteReader();
        while (reader.Read())
        {
            htmlStr = reader.GetInt32(0).ToString();
        }
        reader.Close();
        SqlCOn.Close();            
        return(???)
    }

【问题讨论】:

  • 在表示层,我想将数据阅读器检索到的数据分配给asp标签!

标签: asp.net sql-server sqldatareader


【解决方案1】:

一般来说,您永远不应该将SqlDataReader 返回到数据库访问代码之外的层。这个一般原则背后的原因是SqlDataReader 是一个非常“昂贵”的对象,它保持与数据库的开放连接!因此,如果您保留SqlDataReader,那还不错,但是如果您在任何给定时间保留10 个?其中100个呢? 1000?这是灾难的秘诀。

那么如何关闭从 SqlDataReader 到数据库的连接呢? .NET 在IDisposable 接口中有一个非常方便的方法,称为Dispose(),它将为您处理清理工作。所以你的代码可能看起来像

function getData()
{
    // instantiate SqlDataReader from SqlCommand, call it "rdr"
    rdr.Dispose();
}

但实际上该代码存在问题。如果您的代码在到达Dispose() 之前抛出异常怎么办?它应该看起来像

function getData()
{
    try{
        // instantiate SqlDataReader from SqlCommand, call it "rdr"
    }
    catch(Exception){}
    Finally{
        rdr.Dispose();
    }
}

这很冗长!如果您不想输入所有内容怎么办?别担心,.NET 也为您处理了这个问题。这样做:

public (???) displayCustoemrhShipOrder()
{
    string htmlStr = string.Empty;                   
    string sConnectionString = ConfigurationManager.ConnectionStrings["LGDB"].ToString();
    using(SqlConnection SqlCOn = new SqlConnection(sConnectionString))
    {
    using(SqlCommand SqlCmd = new SqlCommand())
    {
    SqlCmd.Connection = SqlCOn;
    SqlCmd.CommandText = "displayCustomerShipOrder";
    SqlCmd.CommandType = CommandType.StoredProcedure;
    SqlCOn.Open();
    SqlCmd.Parameters.AddWithValue("ShipOrderID",shipOrderID);
    using(SqlDataReader reader = SqlCmd.ExecuteReader())
    while (reader.Read())
    {
        htmlStr = reader.GetInt32(0).ToString();
    }
    // reader.Close();  // this line becomes optional, Dispose() will call Close()
    }
    // SqlCOn.Close();  // this line becomes optional, Dispose() will call Close()
    }
    }

    return(???)
}

这完全是一种迂回的说法,如果你知道你需要Dispose()Close() SqlDataReader,并且一旦你这样做就无法从中获取数据,那么你显然不应该将它返回给编码需要处理数据的内容(但不一定是它占用的数据库连接)。我建议使用DataTable 类,你可以在这里阅读:

.NET DataTable class

另外转换为DataTable的方法称为DataTable.Load(SqlDatareader...

【讨论】:

  • 非常感谢您的全面回答,对于像我这样的初学者非常有用。但是后来我想将数据读取器中的数据分配给asp标签,使用数据表类是真的吗?
  • 数据库访问类可以返回一个DataTable 类实例,然后您可以通过迭代DataTable.Rows 将该DataTable 实例转换为您想要的任何实例,这与DataReader.Read() 完全相同,除了它不会消耗打开的数据库连接。这有点低效,因为您正在对数据进行 2 次迭代,一次在 DataReader 中生成 DataTable,另一次在 DataTable 中生成 List<YourObjectWhichYouWillPassToAspLabel>。您可以通过直接从DataReader.Read中的数据实例化YourObject...来跳过DataTable类
  • 但我不建议您这样做,除非您有更多经验,因为将DataReader 保持打开更长时间,或者甚至将其保持打开更长时间的风险可能会带来巨大的不利影响。收获
【解决方案2】:

您可以将每个单独的值添加到 List<string> 返回并在方法之外使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    相关资源
    最近更新 更多