C# 从ASP.NET返回空白数据表的过程

C# 从ASP.NET返回空白数据表的过程,c#,datatable,sqlcommand,C#,Datatable,Sqlcommand,我试图从ASP.NET控制台应用程序运行的存储过程出现问题 这就是我试图在代码中获得结果的方式: public static DataTable PerformStoredProcedure(int PracticeID, string CommandName) { DataTable dt = new DataTable(); try { using (SqlConnection conn = new SqlC

我试图从ASP.NET控制台应用程序运行的存储过程出现问题

这就是我试图在代码中获得结果的方式:

public static DataTable PerformStoredProcedure(int PracticeID, string CommandName)
    {

        DataTable dt = new DataTable();

        try
        {
            using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["DbConnString"].ToString()))
            {
                conn.Open();

                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = CommandName;
                    cmd.Parameters.AddWithValue("@practiceID", PracticeID);

                    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                    {
                        da.Fill(dt);
                    }
                }

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    for (int j = 0; j < dt.Rows[i].ItemArray.Length; j++)
                    {
                        Console.Write(dt.Rows[i].ItemArray[j] + ",");
                    }
                    Console.WriteLine();
                }
            }
        }
我想我应该包括它,以避免混淆
SqlCommand
是否正确初始化。调整之后,我开始遇到命令返回空白数据表的问题。我假设它可能与数据表
dt
的最小容量有关,所以我调整了它,正如您在原始代码中看到的那样

我已经做了额外的研究,并提出了建议的修复方案,但建议无效:

不计较

使用数据适配器而不是数据读取器

这是最详细的答案。在论坛上有几条建议,但最终的解决方案与数据库默认使用的视图有关,并阻止对所需数据的访问。我已经向我们的DBA确认,我们不会这样做

正如我前面提到的,存储过程中包含的查询是巨大的,我没有将其包括在这里,因为它的大小非常大,而且这篇文章已经足够长了。我再次确认,该程序在SSMS中有效

我还没有包括示例结果集,因为数据包含受限信息

我很感激你能给我的任何帮助

更新:

我添加了另一个调用存储过程的方法,以查看问题是否特定于所调用的特定过程。第二个存储过程还返回了一个空白数据表,因此问题并不特定于这两个过程。(我还确认第二个程序正在运行并返回SSMS中的行)

这让我相信该项目的app.config文件有问题。然后,我添加了第三个方法,该方法调用解决方案中另一个项目上的存储过程。然而,即使这样,也会返回一个空白的数据表


我想我会在遇到他们时提供线索。

你很接近。以下是几点建议:

  • SqlConnection
    从未打开。您需要依次调用
    .Open()
    对于要建立的连接
  • 如果你设定 在
    .Fill()
    行上设置断点,并将鼠标悬停在
    数据表上
    对象,它将看起来好像
    数据表
    为空(如您所见),但是
    .Fill()
    实际上为您填充了
    数据表
    行
    自动(请参阅)。我敢打赌,如果你在
    行中循环,你会发现
    您的查询实际上一直在返回数据
  • 您可以使用
    语句,这些语句会自动为您调用
    .Dispose()
    ,并关闭
    SqlConnection
  • 以下是您的方法的更新版本:

    public static DataTable getAllModifiedChargesToday(int practiceID)
    {
        DataTable dt = new DataTable();
    
        try
        {
            using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["DbConnString"].ToString()))
            {
                conn.Open();
    
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.CommandText = "ch_getAllModifiedChargesToday";
                    cmd.Parameters.AddWithValue("@practiceID", practiceID);
    
                    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                    {
                        da.Fill(dt);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            LogError(ex);
        }
    
        return dt;
    }
    
    您可以运行以下测试来查看返回的数据:

    for (int i = 0; i < dt.Rows.Count; i++)
    {
        for (int j = 0; j < dt.Rows[i].ItemArray.Length; j++)
        {
            Console.Write(dt.Rows[i].ItemArray[j] + ",");
        }
        Console.WriteLine();
    }
    

    您根本不需要额外的
    CommandFactory
    类,也不需要设置
    MinimumCapacity
    (),除非您确实在尝试优化性能,并对返回的记录数量进行猜测。此属性不常使用。

    谢谢您的建议。不幸的是,这个命令的结果仍然是一个空的{}数据表。我不想让你挂断--我会在有机会的时候再看一看。谢谢兄弟。非常有趣。我明白了为什么不需要命令工厂类。当我实现您的建议时,对于原始查询,它仍然返回一个空白数据表,但是对于我在编辑中提到的第二个查询,它按预期返回了7行。我确认原始查询在SSMS中工作,所以我有点困惑。我会再挖一些。谢谢你,你帮了大忙,不客气。你可以发布你的更新代码,但仍然不起作用吗?您在测试中是否通过了与SSMS中相同的@practiceID值?
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        for (int j = 0; j < dt.Rows[i].ItemArray.Length; j++)
        {
            Console.Write(dt.Rows[i].ItemArray[j] + ",");
        }
        Console.WriteLine();
    }
    
    "Server=SERVER;Database=DATABASE;User ID=USER;Password=PASSWORD;Trusted_Connection=False;Asynchronous Processing=true;Timeout=60;"