我如何检查看看一个列是否存在于一个SqlDataReader对象?在我的数据访问层,我创建了一个为多个存储过程调用构建相同对象的方法。其中一个存储过程具有其他存储过程不使用的附加列。我想修改方法以适应各种情况。
我的应用程序是用c#编写的。
我如何检查看看一个列是否存在于一个SqlDataReader对象?在我的数据访问层,我创建了一个为多个存储过程调用构建相同对象的方法。其中一个存储过程具有其他存储过程不使用的附加列。我想修改方法以适应各种情况。
我的应用程序是用c#编写的。
当前回答
你也可以调用GetSchemaTable()在你的DataReader上,如果你想要列的列表,你不想得到一个异常…
其他回答
以下是Jasmine给出的解决方案。(还有一个,虽然很简单!)
reader.GetSchemaTable().Select("ColumnName='MyCol'").Length > 0;
你也可以调用GetSchemaTable()在你的DataReader上,如果你想要列的列表,你不想得到一个异常…
public static class DataRecordExtensions
{
public static bool HasColumn(this IDataRecord dr, string columnName)
{
for (int i=0; i < dr.FieldCount; i++)
{
if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
return true;
}
return false;
}
}
在控制逻辑中使用异常被认为是不好的做法,并且会带来性能损失。它还会将抛出的# exceptions错误消息发送给分析器,并帮助任何人设置调试器在抛出异常时中断。
GetSchemaTable()也是许多答案中的另一个建议。这不是检查字段是否存在的首选方法,因为它不是在所有版本中都实现的(它是抽象的,并且在dotnetcore的某些版本中抛出NotSupportedException)。GetSchemaTable在性能方面也是过度消耗的,因为如果您查看源代码,它是一个相当繁重的函数。
如果您经常使用循环遍历字段,则可能会对性能造成较小的影响,您可能需要考虑缓存结果。
这段代码纠正了Levitikon在他们的代码中遇到的问题: (改编自:[1]:http://msdn.microsoft.com/en-us/library/system.data.datatablereader.getschematable.aspx)
public List<string> GetColumnNames(SqlDataReader r)
{
List<string> ColumnNames = new List<string>();
DataTable schemaTable = r.GetSchemaTable();
DataRow row = schemaTable.Rows[0];
foreach (DataColumn col in schemaTable.Columns)
{
if (col.ColumnName == "ColumnName")
{
ColumnNames.Add(row[col.Ordinal].ToString());
break;
}
}
return ColumnNames;
}
获取所有那些无用的列名,而不是从表中获取列名的原因是…… 是因为您正在获取模式列的名称(即schema表的列名)
注意:这似乎只返回第一列的名称…
EDIT:返回所有列名称的修正代码,但不能使用SqlDataReader来完成
public List<string> ExecuteColumnNamesReader(string command, List<SqlParameter> Params)
{
List<string> ColumnNames = new List<string>();
SqlDataAdapter da = new SqlDataAdapter();
string connection = ""; // your sql connection string
SqlCommand sqlComm = new SqlCommand(command, connection);
foreach (SqlParameter p in Params) { sqlComm.Parameters.Add(p); }
da.SelectCommand = sqlComm;
DataTable dt = new DataTable();
da.Fill(dt);
DataRow row = dt.Rows[0];
for (int ordinal = 0; ordinal < dt.Columns.Count; ordinal++)
{
string column_name = dt.Columns[ordinal].ColumnName;
ColumnNames.Add(column_name);
}
return ColumnNames; // you can then call .Contains("name") on the returned collection
}
下面的方法很简单,对我来说很有效:
bool hasMyColumn = (reader.GetSchemaTable().Select("ColumnName = 'MyColumnName'").Count() == 1);