使用 IEnumerable<IDataRecord> 到 return 数据
Using IEnumerable<IDataRecord> to return data
我正在尝试 return 使用具有给定字段的 IEnumerable 的数据,我正在调用我想引用具有给定字段名称和 return 的数据的方法。
例子,这里是函数
public IEnumerable<IDataRecord> GetSomeData(string fields, string table, string where = null, int count = 0)
{
string sql = "SELECT @Fields FROM @Table WHERE @Where";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@Fields", SqlDbType.NVarChar, 255).Value = where;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
通话中:
IEnumerable<IDataRecord> data = bw.GetSomeData("StaffCode, Perms", "BW_Staff", "StaffCode = 'KAA'");
我必须如何 return 以这种方式或以何种方式处理数据?
string staffCode = data["StaffCode"].ToString();
string perms = data["Perms"].ToString();
感谢您的帮助
您的数据变量是行的集合。您需要遍历集合以对每一行做一些有趣的事情。
foreach (var row in data)
{
string staffCode = row["StaffCode"].ToString();
string perms = row["Perms"].ToString();
}
更新:
根据您的评论,您只希望 GetSomeData(...) return 一行,我建议两件事中的一件。
将 GetSomeData 的签名更改为 return IDataRecord。并从实施中删除 "yield"。
public IDataRecord GetSomeData(string fields, string table, string where = null, int count = 0)
{
string sql = "SELECT @Fields FROM @Table WHERE @Where";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@Fields", SqlDbType.NVarChar, 255).Value = where;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
return (IDataRecord)rdr;
}
}
}
}
}
或
var row = data.FirstOrDefault();
if (row != null)
{
string staffCode = row["StaffCode"].ToString();
string perms = row["Perms"].ToString();
}
备注:
您的 GetSomeData 实现不完整。您甚至没有使用几个参数,最重要的是 fields 参数。从概念上讲,在 SQL 中,您无法参数化哪些字段得到 returned 或哪些 table 被使用(等等),而是您需要构建一个动态查询并执行它。
更新 2
这是构造正确查询的 GetSomeData 的实现(在 C# 6 中,如果您在早期版本中需要它,请告诉我)。
public IEnumerable<IDataRecord> GetSomeData(IEnumerable<string> fields, string table, string where = null, int count = 0)
{
var predicate = string.IsNullOrWhiteSpace(where) ? "" : " WHERE " + where;
string sql = $"SELECT { string.Join(",", fields) } FROM {table} {predicate}";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
下面是您将如何使用它。
IEnumerable<IDataRecord> data = bw.GetSomeData(new[] { "StaffCode", "Perms" }, "BW_Staff", "StaffCode = 'KAA'");
您可以枚举它或调用.FirstOrDefault,这是您的选择。每次调用 GetSomeData 时,它都会 运行 查询。
更新 3
使用早期版本的 C# 实现的 GetSomeData
public IEnumerable<IDataRecord> GetSomeData(IEnumerable<string> fields, string table, string where = null, int count = 0)
{
var predicate = string.IsNullOrEmpty(where) ? "" : " WHERE " + where;
string sql = string.Format("SELECT {0} FROM {1} {2}", string.Join(",", fields), table, predicate);
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
我正在尝试 return 使用具有给定字段的 IEnumerable 的数据,我正在调用我想引用具有给定字段名称和 return 的数据的方法。
例子,这里是函数
public IEnumerable<IDataRecord> GetSomeData(string fields, string table, string where = null, int count = 0)
{
string sql = "SELECT @Fields FROM @Table WHERE @Where";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@Fields", SqlDbType.NVarChar, 255).Value = where;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
通话中:
IEnumerable<IDataRecord> data = bw.GetSomeData("StaffCode, Perms", "BW_Staff", "StaffCode = 'KAA'");
我必须如何 return 以这种方式或以何种方式处理数据?
string staffCode = data["StaffCode"].ToString();
string perms = data["Perms"].ToString();
感谢您的帮助
您的数据变量是行的集合。您需要遍历集合以对每一行做一些有趣的事情。
foreach (var row in data)
{
string staffCode = row["StaffCode"].ToString();
string perms = row["Perms"].ToString();
}
更新:
根据您的评论,您只希望 GetSomeData(...) return 一行,我建议两件事中的一件。
将 GetSomeData 的签名更改为 return IDataRecord。并从实施中删除 "yield"。
public IDataRecord GetSomeData(string fields, string table, string where = null, int count = 0)
{
string sql = "SELECT @Fields FROM @Table WHERE @Where";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@Fields", SqlDbType.NVarChar, 255).Value = where;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
return (IDataRecord)rdr;
}
}
}
}
}
或
var row = data.FirstOrDefault();
if (row != null)
{
string staffCode = row["StaffCode"].ToString();
string perms = row["Perms"].ToString();
}
备注:
您的 GetSomeData 实现不完整。您甚至没有使用几个参数,最重要的是 fields 参数。从概念上讲,在 SQL 中,您无法参数化哪些字段得到 returned 或哪些 table 被使用(等等),而是您需要构建一个动态查询并执行它。
更新 2
这是构造正确查询的 GetSomeData 的实现(在 C# 6 中,如果您在早期版本中需要它,请告诉我)。
public IEnumerable<IDataRecord> GetSomeData(IEnumerable<string> fields, string table, string where = null, int count = 0)
{
var predicate = string.IsNullOrWhiteSpace(where) ? "" : " WHERE " + where;
string sql = $"SELECT { string.Join(",", fields) } FROM {table} {predicate}";
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
下面是您将如何使用它。
IEnumerable<IDataRecord> data = bw.GetSomeData(new[] { "StaffCode", "Perms" }, "BW_Staff", "StaffCode = 'KAA'");
您可以枚举它或调用.FirstOrDefault,这是您的选择。每次调用 GetSomeData 时,它都会 运行 查询。
更新 3
使用早期版本的 C# 实现的 GetSomeData
public IEnumerable<IDataRecord> GetSomeData(IEnumerable<string> fields, string table, string where = null, int count = 0)
{
var predicate = string.IsNullOrEmpty(where) ? "" : " WHERE " + where;
string sql = string.Format("SELECT {0} FROM {1} {2}", string.Join(",", fields), table, predicate);
using (SqlConnection cn = new SqlConnection(db.getDBstring(Globals.booDebug)))
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}