如何同时获取行数和行数
How to get rows and count of rows simultaneously
我有一个同时 returns rows
和 count
的存储过程。
我尝试遵循 ADO.net
代码,但我得到 IndexOutOfRange
ItemCount 异常(ItemCount 包含 count
行)
public List<Product> GetProductDetails(Product p)
{
List<Product> products = new List<Product>();
using (SqlConnection con = new SqlConnection(_connectionString))
{
SqlCommand cmd = new SqlCommand("[usp_Get_ServerPagedProducts]", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@rvcName", System.Data.SqlDbType.VarChar).Value = p.Name;
cmd.Parameters.AddWithValue("@rvcCode", System.Data.SqlDbType.VarChar).Value = p.Code;
cmd.Parameters.AddWithValue("@riProductTypeID", System.Data.SqlDbType.Int).Value = p.ProductTypeID;
cmd.Parameters.AddWithValue("@ristartIndex", System.Data.SqlDbType.Int).Value = p.RowIndex;
cmd.Parameters.AddWithValue("@rimaxRows", System.Data.SqlDbType.Int).Value = p.PageSize;
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Product product = new Product(reader["Name"].ToString(), reader["Code"].ToString(), reader["Description"].ToString(), (DateTime)reader["DateCreated"], Convert.ToInt32(reader["ProductID"]), Convert.ToInt32(reader["ProductTypeID"]), reader["ProductTypeName"].ToString(), Convert.ToInt32(reader["ItemCount"]));
products.Add(product);
}
}
}
return products;
}
存储过程:
SELECT ProductID,
Name,
[Description],
Code,
DateCreated,
ProductTypeID,
ProductTypeName
FROM (
SELECT P.pkProductID AS ProductID,
P.Name AS Name,
P.[Description] AS [Description],
P.Code AS Code,
P.DateCreated AS DateCreated,
P.fkProductTypeID AS ProductTypeID,
PT.Name AS ProductTypeName,
ROW_NUMBER() OVER (ORDER BY P.pkProductID) AS RowNumber
FROM Product P
INNER JOIN ProductType PT ON PT.pkProductTypeID = P.fkProductTypeID
WHERE P.Name LIKE '%' + @rvcName + '%'
AND P.Code LIKE '%' + @rvcCode + '%'
AND (@riProductTypeID = 0 OR P.fkProductTypeID = @riProductTypeID)
) AS tblProduct
WHERE RowNumber >= @ristartIndex
AND RowNumber < (@ristartIndex + @rimaxRows)
SELECT COUNT(*) AS ItemCount
FROM (
SELECT P.pkProductID,
P.Name,
P.[Description],
P.Code,
P.DateCreated,
P.fkProductTypeID AS 'ProductTypeID',
PT.Name AS 'ProductTypeName',
ROW_NUMBER() OVER (ORDER BY P.Name DESC) AS RowNumber
FROM Product P
INNER JOIN ProductType PT ON PT.pkProductTypeID = P.fkProductTypeID
WHERE P.Name LIKE '%' + @rvcName + '%'
AND P.Code LIKE '%' + @rvcCode + '%'
AND (@riProductTypeID = 0 OR P.fkProductTypeID = @riProductTypeID)
) AS TotalCount
是不是返回了两张表?有什么解决办法?
检查存储过程返回的列名。它可能是打字错误或 "ItemCount".
以外的其他内容
根据 SqlDataReader.Item Property 的文档,如果没有找到具有指定名称的列,则会抛出 IndexOutOfRange 异常。
如果 return 多个记录集,则必须使用 NextResult
:
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Product product = new Product();
product.Name = reader["Name"].ToString();
product.Code = reader["Code"].ToString();
// ...
products.Add(product);
}
if (reader.NextResult() && reader.Read())
{
int itemCount = reader.GetInt32(reader.GetOrdinal("ItemCount"));
foreach(Product p in products)
p.ItemCount = itemCount;
}
}
但我认为最好在第一个查询中包含总数。然后它更简单,你不需要最终循环。数据库可以应付这样的子查询。如果不是相关子查询,优化器将确保它只执行一次。
我有一个同时 returns rows
和 count
的存储过程。
我尝试遵循 ADO.net
代码,但我得到 IndexOutOfRange
ItemCount 异常(ItemCount 包含 count
行)
public List<Product> GetProductDetails(Product p)
{
List<Product> products = new List<Product>();
using (SqlConnection con = new SqlConnection(_connectionString))
{
SqlCommand cmd = new SqlCommand("[usp_Get_ServerPagedProducts]", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@rvcName", System.Data.SqlDbType.VarChar).Value = p.Name;
cmd.Parameters.AddWithValue("@rvcCode", System.Data.SqlDbType.VarChar).Value = p.Code;
cmd.Parameters.AddWithValue("@riProductTypeID", System.Data.SqlDbType.Int).Value = p.ProductTypeID;
cmd.Parameters.AddWithValue("@ristartIndex", System.Data.SqlDbType.Int).Value = p.RowIndex;
cmd.Parameters.AddWithValue("@rimaxRows", System.Data.SqlDbType.Int).Value = p.PageSize;
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Product product = new Product(reader["Name"].ToString(), reader["Code"].ToString(), reader["Description"].ToString(), (DateTime)reader["DateCreated"], Convert.ToInt32(reader["ProductID"]), Convert.ToInt32(reader["ProductTypeID"]), reader["ProductTypeName"].ToString(), Convert.ToInt32(reader["ItemCount"]));
products.Add(product);
}
}
}
return products;
}
存储过程:
SELECT ProductID,
Name,
[Description],
Code,
DateCreated,
ProductTypeID,
ProductTypeName
FROM (
SELECT P.pkProductID AS ProductID,
P.Name AS Name,
P.[Description] AS [Description],
P.Code AS Code,
P.DateCreated AS DateCreated,
P.fkProductTypeID AS ProductTypeID,
PT.Name AS ProductTypeName,
ROW_NUMBER() OVER (ORDER BY P.pkProductID) AS RowNumber
FROM Product P
INNER JOIN ProductType PT ON PT.pkProductTypeID = P.fkProductTypeID
WHERE P.Name LIKE '%' + @rvcName + '%'
AND P.Code LIKE '%' + @rvcCode + '%'
AND (@riProductTypeID = 0 OR P.fkProductTypeID = @riProductTypeID)
) AS tblProduct
WHERE RowNumber >= @ristartIndex
AND RowNumber < (@ristartIndex + @rimaxRows)
SELECT COUNT(*) AS ItemCount
FROM (
SELECT P.pkProductID,
P.Name,
P.[Description],
P.Code,
P.DateCreated,
P.fkProductTypeID AS 'ProductTypeID',
PT.Name AS 'ProductTypeName',
ROW_NUMBER() OVER (ORDER BY P.Name DESC) AS RowNumber
FROM Product P
INNER JOIN ProductType PT ON PT.pkProductTypeID = P.fkProductTypeID
WHERE P.Name LIKE '%' + @rvcName + '%'
AND P.Code LIKE '%' + @rvcCode + '%'
AND (@riProductTypeID = 0 OR P.fkProductTypeID = @riProductTypeID)
) AS TotalCount
是不是返回了两张表?有什么解决办法?
检查存储过程返回的列名。它可能是打字错误或 "ItemCount".
以外的其他内容根据 SqlDataReader.Item Property 的文档,如果没有找到具有指定名称的列,则会抛出 IndexOutOfRange 异常。
如果 return 多个记录集,则必须使用 NextResult
:
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Product product = new Product();
product.Name = reader["Name"].ToString();
product.Code = reader["Code"].ToString();
// ...
products.Add(product);
}
if (reader.NextResult() && reader.Read())
{
int itemCount = reader.GetInt32(reader.GetOrdinal("ItemCount"));
foreach(Product p in products)
p.ItemCount = itemCount;
}
}
但我认为最好在第一个查询中包含总数。然后它更简单,你不需要最终循环。数据库可以应付这样的子查询。如果不是相关子查询,优化器将确保它只执行一次。