Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回SqlDataReader_C#_Ado.net - Fatal编程技术网

C# 返回SqlDataReader

C# 返回SqlDataReader,c#,ado.net,C#,Ado.net,我有以下代码: public static SqlDataReader GetGeneralInformation ( int RecID ) { using ( var conn = new SqlConnection( GetConnectionString() ) ) using ( var cmd = conn.CreateCommand() ) { conn.Open(); cmd.CommandText = @"

我有以下代码:

public static SqlDataReader GetGeneralInformation ( int RecID )
{
    using ( var conn = new SqlConnection( GetConnectionString() ) )
    using ( var cmd = conn.CreateCommand() )
    {
        conn.Open();
        cmd.CommandText =
        @"SELECT cs.Status, cs.Completed
          FROM NC_Steps s
          INNER JOIN NC_ClientSteps cs
              ON cs.RecID = s.RecID
          WHERE cs.ClientID = 162
          AND s.RecID = @value";
        cmd.Parameters.AddWithValue( "@value", RecID );
        using ( var reader = cmd.ExecuteReader() )
        {
            if ( reader.Read() )
            {
                return reader;
            }
            return null;
        }
    }
}
我如何引用这个

我试过了,但没用

SqlDataReader reader = GeneralFunctions.GetGeneralInformation();
还有,我如何从读者那里阅读

Reader.GetString( reader.GetOrdinal( "Status" ) )
编辑

我现在得到以下错误:

异常详细信息:System.NullReferenceException:对象引用不存在 设置为对象的实例

以下是更新的代码:

public static IEnumerable<IDataRecord> GetGeneralInformation ( int ClientID )
{
    using ( var conn = new SqlConnection( GetConnectionString() ) )
    using ( var cmd = conn.CreateCommand() )
    {
        conn.Open();
        cmd.CommandText =
        @"SELECT i.GoLiveDate, i.FirstBonusRun, i.TechFName, i.TechLName, i.TechEmail, i.TechPhone, i.WebISPFName, i.WebISPLName, 
          i.WebISPEmail, i.WebISPPhone, i.FullFillFName, i.FullFillLName, i.FullFillEmail, i.FullFillPhone, d.FName,
          d.LName, d.HomePhone, d.Email
          FROM NC_Information i
          INNER JOIN Distributor d
            ON d.DistID = i.ClientID
          WHERE clientID = @value";
        cmd.Parameters.AddWithValue( "@value", ClientID );
        using ( var reader = cmd.ExecuteReader() )
        {
            while ( reader.Read() )
            {
                yield return reader;
            }
            yield return null;
        }
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    IEnumerable<IDataRecord> reader = GeneralFunctions.GetGeneralInformation( (int)Session[ "DistID" ] );

    //string result = GeneralFunctions.GetGeneralInformation( Globals.GeneralInformation ).First()[ "Status" ].ToString();
}
公共静态IEnumerable GetGeneralInformation(int-ClientID)
{
使用(var conn=new SqlConnection(GetConnectionString()))
使用(var cmd=conn.CreateCommand())
{
conn.Open();
cmd.CommandText=
@“选择i.GoLiveDate、i.FirstBonusRun、i.TechFName、i.TechLName、i.TechEmail、i.TechPhone、i.WebISPFName、i.WebISPLName,
i、 WebISPEmail,i.WebISPPhone,i.FullFillFName,i.FullFillName,i.FullFillEmail,i.FullFillPhone,d.FName,
d、 L姓名,d.家庭电话,d.电子邮件
来自NC_信息i
内连接分配器d
在d.DistID=i.ClientID上
其中clientID=@value”;
cmd.Parameters.AddWithValue(“@value”,ClientID);
使用(var reader=cmd.ExecuteReader())
{
while(reader.Read())
{
回传阅读器;
}
收益返回空;
}
}
}
受保护的无效页面加载(对象发送方、事件参数e)
{
IEnumerable reader=GeneralFunctions.GetGeneralInformation((int)会话[“DistID]”);
//字符串结果=GeneralFunctions.GetGeneralInformation(Globals.GeneralInformation).First()[“Status”].ToString();
}

问题在于离开函数(通过返回语句)会将您踢出使用块的
,因此您正在使用的
SqlDataReader
SqlConnections
会被释放。要解决此问题,请尝试如下更改函数签名:

public static IEnumerable<IDataRecord> GetGeneralInformation ( int RecID )
using ( var reader = cmd.ExecuteReader() )
{
    while ( reader.Read() )
    {
        yield return reader;
    }
}
int RecID = 12345;
string result = GetGeneralInformation(RecID).First()["Status"].ToString();
最后一部分“我如何从中阅读?”可能如下所示:

public static IEnumerable<IDataRecord> GetGeneralInformation ( int RecID )
using ( var reader = cmd.ExecuteReader() )
{
    while ( reader.Read() )
    {
        yield return reader;
    }
}
int RecID = 12345;
string result = GetGeneralInformation(RecID).First()["Status"].ToString();

根据定义,
using
语句应该在调用对象后处理该对象


因此,在返回数据读取器后,它将被处理。

问题是您正在方法中创建数据库连接

如果要在多个方法之间共享数据库资源,请将
SqlConnection
移出此范围

这样,您可以从该函数返回读取器,读取器将保持不变


另外,不要在这个函数中
.Read()
,只需返回对象。

将连接字符串添加到app.config或web.config中的AppSettings部分

   public string GetSqlConnection()
    {
        return  System.Configuration.ConfigurationManager.AppSettings["SqlConnectionString"];
    }
//函数返回SqlDataReader结果

    public SqlDataReader executeReader(string sql, SqlParameter[] parameters=null)
    {
        SqlConnection conn = new SqlConnection();
        conn.ConnectionString = GetSqlConnection();
        conn.Open();
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandText = sql;
        if (parameters != null)
        {
            cmd.CommandType = CommandType.StoredProcedure;
            foreach (SqlParameter p in parameters)
            {
                cmd.Parameters.Add(p);
            }
        }
        else
        {
            cmd.CommandType = CommandType.Text;
        }
        SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        return reader;
    }
要使用该功能,请执行以下操作:

        string query = @"SELECT cs.Status, cs.Completed
      FROM NC_Steps s
      INNER JOIN NC_ClientSteps cs
          ON cs.RecID = s.RecID
      WHERE cs.ClientID = 162
      AND s.RecID = @value";
       //you can add more parameters by adding commas
       var parameters = new SqlParameter[] {
            new SqlParameter("@value", RecID )
           };

        SqlDataReader dr = executeReader(query, parameters);
        while (dr.Read())
        {
            //fill your controls with data 
        }
        dr.Close();

我认为值得一提。一个非常简单且易于使用的解决方案。

为什么您不能像其他SqlDataReader一样阅读它?它失败了吗?如果是这样,那是因为您使用了
语句。您正在使用读卡器之前关闭连接。您可以返回从读卡器填充的对象。你还没有说什么不起作用。@JamesWilson:我会重构它-将读取器“泄漏”到另一个方法(即使你能使它起作用)不是一个好的设计,只返回结果。我根本不会直接使用ADO.NET。我会使用实体框架或其他抽象层。我也会在一个单独的数据访问层类库中完成。您不应该在网页中直接访问数据(尽管我有时会对数据源控件进行例外)。@BrokenGlass-不喜欢使用列表保存数据库中的数据。。。他们忽略了使用datareader vs datatable/dataset的全部意义,即一次只在RAM中保存一条记录。您能帮我理解IEnumerable和yield的作用吗?如果没有,我可以查一下,不管怎样我都很感激你的答案。@BrokenGlass-试试看,效果很好。代码在后台被“提升”到一个单独的类中,直到枚举之后才到达dispose。@JamesWilson yield关键字创建了一个所谓的“迭代器”。它是一个知道如何在某种集合上循环的对象。IEnumerable是描述SqlDataReader重要部分的另一种方式。你可以在foreach(;)循环中使用它。然后你需要一种方法来解释它。。。但现在你有了一个全新的问题。@James:这就是我害怕的。从using语句返回时,读取器关闭。初始化一个自定义对象,如下面的回答所示:你在说什么?你不需要收益。去试试看。它可能不起作用,但肯定会编译。