Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.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# Sql DataReader有行,但返回的数据为空_C#_Sql_Sql Server_Database_Sqlcmd - Fatal编程技术网

C# Sql DataReader有行,但返回的数据为空

C# Sql DataReader有行,但返回的数据为空,c#,sql,sql-server,database,sqlcmd,C#,Sql,Sql Server,Database,Sqlcmd,我正在使用查询从sql数据库中选择数据。它有行,但dataraader.Read()函数返回false,并且正如我在调试中检查的那样,行是空的 我一直使用的代码是 public void getSale() { DB db = new DB(); try { db.cmd.CommandText = "select * from Sale where date is not null and (date betw

我正在使用查询从sql数据库中选择数据。它有行,但data
raader.Read()
函数返回
false
,并且正如我在调试中检查的那样,行是空的

我一直使用的代码是

public void getSale()
    {
        DB db = new DB();

        try
        {
            db.cmd.CommandText = "select * from Sale where date is not null and (date between '"+StartDate+"' and '"+EndDate+"') order by date";
            db.cmd.Connection = db.con;
            db.con.Open();

            if(db.con.State == System.Data.ConnectionState.Open)
            {
                db.dataReader = db.cmd.ExecuteReader();

                if(db.dataReader.HasRows)
                {
                    while(db.dataReader.Read())
                    {
                        SaleModel sm = new SaleModel();
                        sm.SaleId = long.Parse(db.dataReader["Id"].ToString());
                        sm.UserName = db.dataReader["UserName"].ToString();
                        sm.ItemsQuantity = int.Parse(db.dataReader["ItemsQuantity"].ToString());
                        sm.TotalAmount = double.Parse(db.dataReader["TotalAmount"].ToString());
                        sm.SubTotal = double.Parse(db.dataReader["SubTotal"].ToString());
                        sm.Discount = double.Parse(db.dataReader["Discount"].ToString());
                        sm.Completed = bool.Parse(db.dataReader["Completed"].ToString());
                        sm.Date = DateTime.Parse(db.dataReader["Date"].ToString());
                        sm.CustomerPhone = long.Parse(db.dataReader["CustomerPhone"].ToString());

                        SalesList.Add(sm);
                    }

                    db.con.Close();
                }
            }
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
        }
    }
当我在VisualStudio中的查询编辑器上测试此查询时,返回了行


如果有人能提供帮助?

除了您使用的是
date
这是一个保留字,而不是您的实际列名之外,您看不到任何问题。将您的查询更改为

db.cmd.CommandText = "select * from Sale where [date] is not null and ([date] between '"+StartDate+"' and '"+EndDate+"') order by [date]";

为什么要连接字符串来构建sql查询?永远不要那样做。它是sql注入的源代码,可能会导致类似这样的问题。而是使用参数化查询

也不要像
DB
类那样使用
SqlConnection
包装器。这可能会导致。而是在需要的地方创建、打开、关闭和处置它们,最好使用
-statement。连接池将为您管理其余部分

public List<SaleModel> GetSale(DateTime startDate, DateTime endDate)
{
    string sql = @"select * from Sale 
                   where date is not null 
                   and date between @StartDate and @EndDate 
                   order by date";

    var salesList = new List<SaleModel>();

    try
    {
        using (var con = new SqlConnection("insert your connection string"))
        using (var cmd = new SqlCommand(sql, con))
        {
            cmd.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = startDate;
            cmd.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = endDate;
            con.Open();
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    SaleModel sm = new SaleModel();
                    sm.SaleId = long.Parse(reader["Id"].ToString());
                    sm.UserName = reader["UserName"].ToString();
                    sm.ItemsQuantity = int.Parse(reader["ItemsQuantity"].ToString());
                    sm.TotalAmount = double.Parse(reader["TotalAmount"].ToString());
                    sm.SubTotal = double.Parse(reader["SubTotal"].ToString());
                    sm.Discount = double.Parse(reader["Discount"].ToString());
                    sm.Completed = bool.Parse(reader["Completed"].ToString());
                    sm.Date = DateTime.Parse(reader["Date"].ToString());
                    sm.CustomerPhone = long.Parse(reader["CustomerPhone"].ToString());

                    salesList.Add(sm);
                }
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
    }

    return salesList;
}
public List GetSale(DateTime startDate,DateTime endDate)
{
字符串sql=@“从销售中选择*
其中日期不为空
日期介于@StartDate和@EndDate之间
按日期订购”;
var salesList=新列表();
尝试
{
使用(var con=newsqlconnection(“插入您的连接字符串”))
使用(var cmd=newsqlcommand(sql,con))
{
cmd.Parameters.Add(“@StartDate”,SqlDbType.DateTime).Value=StartDate;
cmd.Parameters.Add(“@EndDate”,SqlDbType.DateTime).Value=EndDate;
con.Open();
使用(var reader=cmd.ExecuteReader())
{
while(reader.Read())
{
SaleModel sm=新SaleModel();
sm.SaleId=long.Parse(reader[“Id”].ToString());
sm.UserName=reader[“UserName”].ToString();
sm.ItemsQuantity=int.Parse(reader[“ItemsQuantity”].ToString());
sm.TotalAmount=double.Parse(读卡器[“TotalAmount”].ToString());
sm.SubTotal=double.Parse(reader[“SubTotal”].ToString());
sm.Discount=double.Parse(reader[“Discount”].ToString());
sm.Completed=bool.Parse(reader[“Completed”].ToString());
sm.Date=DateTime.Parse(reader[“Date”].ToString());
sm.CustomerPhone=long.Parse(读卡器[“CustomerPhone”].ToString());
salesList.Add(sm);
}
}
}
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message,“异常”,MessageBoxButton.OK,MessageBoxImage.Error,MessageBoxResult.OK);
}
退货销售清单;
}
我很确定这是可行的(f.e.可能是一个本地化问题)


旁注:一个方法
GetSale
应该返回一个
列表
,但不能填充列表。您还应该将参数作为
DateTime
传递给方法。我在我的代码示例中对其进行了更改。

这是一种更好的构建代码的方法,它也很有可能解决您的问题:

//accept the date values as parameter arguments, return the result. 
//  Do NOT mess about with variables at the global or class scope.
public IEnumerable<SalesModel> getSale(DateTime StartDate, DateTime EndDate)
{
    string sql = "select * from Sale where date is not null and (date between @StartDate and @EndDate) order by date";

    //DON'T abstract SqlCommand/SqlConnection. DO abstract your connection string.
    //Also, don't bother with the try/catch at this level. You can't really do anything with it here, so worry about the exception in calling code.
    using (var cn = new SqlConnection(DB.ConnectionString))
    using (var cmd = new SqlCommand(sql, cn))
    {
        cmd.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = StartDate
        cmd.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = EndDate
        cn.Open();

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            while(rdr.Read())
            {
                var sm = new SaleModel();
                //If you have good schema design, these values are **already** in the correct type. 
                // The old code forces an expensive conversion to string, following by an expensive parse back to the type it already had.
                // We can do MUCH better.

                sm.SaleId = (long)rdr["Id"];
                //but it is okay for types that are *already* strings
                sm.UserName = rdr["UserName"].ToString();
                sm.ItemsQuantity = (int)rdr["ItemsQuantity"];
                sm.TotalAmount = (double)rdr["TotalAmount"]);
                sm.SubTotal = (double)rdr["SubTotal"];
                sm.Discount = (double)rdr["Discount"];
                sm.Completed = (bool)rdr["Completed"];
                sm.Date = (DateTime)rdr["Date"];
                sm.CustomerPhone = (long).rdr["CustomerPhone"];

                yield return sm;
            }
        }
    }
}
//接受日期值作为参数参数,返回结果。
//不要在全局或类范围内处理变量。
公共IEnumerable getSale(日期时间开始日期、日期时间结束日期)
{
string sql=“从销售中选择*日期不为空,并且(日期介于@StartDate和@EndDate之间)按日期订购”;
//不要抽象SqlCommand/SqlConnection。要抽象连接字符串。
//另外,不要在这个级别上使用try/catch,在这里你真的不能用它做任何事情,所以要担心调用代码时的异常。
使用(var cn=new-SqlConnection(DB.ConnectionString))
使用(var cmd=newsqlcommand(sql,cn))
{
cmd.Parameters.Add(“@StartDate”,SqlDbType.DateTime)。Value=StartDate
cmd.Parameters.Add(“@EndDate”,SqlDbType.DateTime).Value=EndDate
cn.Open();
使用(SqlDataReader rdr=cmd.ExecuteReader())
{
while(rdr.Read())
{
var sm=新的SaleModel();
//如果您具有良好的架构设计,则这些值**已经**为正确的类型。
//旧代码强制将昂贵的转换为字符串,随后是一个昂贵的解析返回到它已经拥有的类型。
//我们可以做得更好。
sm.SaleId=(长)rdr[“Id”];
//但对于已经是字符串的类型来说,这是可以接受的
sm.UserName=rdr[“UserName”].ToString();
sm.ItemsQuantity=(int)rdr[“ItemsQuantity”];
sm.TotalAmount=(双)rdr[“TotalAmount”];
sm.小计=(双倍)rdr[“小计”];
sm.折扣=(双)rdr[“折扣”];
sm.Completed=(bool)rdr[“Completed”];
sm.Date=(DateTime)rdr[“日期”];
sm.CustomerPhone=(长).rdr[“CustomerPhone”];
收益率;
}
}
}
}
在这里,它再次没有所有额外的评论。这里的要点是,与使用字符串连接的原始代码相比,这仍然是更少的代码,并且编写它所用的时间不到10分钟。好的代码不一定需要更长的时间

public IEnumerable<SalesModel> getSale(DateTime StartDate, DateTime EndDate)
{
    string sql = "select * from Sale where date is not null and (date between @StartDate and @EndDate) order by date";

    using (var cn = new SqlConnection(DB.ConnectionString))
    using (var cmd = new SqlCommand(sql, cn))
    {
        cmd.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = StartDate
        cmd.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = EndDate
        cn.Open();

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            while(rdr.Read())
            {
                var sm = new SaleModel();
                sm.SaleId = (long)rdr["Id"];
                sm.UserName = rdr["UserName"].ToString();
                sm.ItemsQuantity = (int)rdr["ItemsQuantity"];
                sm.TotalAmount = (double)rdr["TotalAmount"]);
                sm.SubTotal = (double)rdr["SubTotal"];
                sm.Discount = (double)rdr["Discount"];
                sm.Completed = (bool)rdr["Completed"];
                sm.Date = (DateTime)rdr["Date"];
                sm.CustomerPhone = (long).rdr["CustomerPhone"];

                yield return sm;
            }
        }
    }
}
public IEnumerable getSale(日期时间开始日期、日期时间结束日期)
{
string sql=“从销售中选择*日期不为空,并且(日期介于@StartDate和@EndDate之间)按日期订购”;
使用(var cn=new-SqlConnection(DB.ConnectionString))
使用(var cmd=newsqlcommand(sql,cn))
{
cmd.Parameters.Add(“@StartDate”,SqlDbType.DateTime)。Value=StartDate
cmd.Parameters.Add(“@EndDate”,SqlDbType.DateTime).Value=EndDate
cn.Open();
使用(SqlDataReader rdr=cmd.ExecuteReader())
{
while(rdr.Read())
{
var sm=新的SaleModel();