使用此
有什么好处 private static IEnumerable<string> GetColumnNames(this IDataReader reader)
{
for (int i = 0; i < reader.FieldCount; i++)
yield return reader.GetName(i);
}
而不是
private static string[] GetColumnNames(this IDataReader reader)
{
var columnNames = new string[reader.FieldCount];
for (int i = 0; i < reader.FieldCount; i++)
columnNames[i] = reader.GetName(i);
return columnNames;
}
以下是我使用此方法的方法
int orderId = _noOrdinal;
IEnumerable<string> columnNames = reader.GetColumnNames();
if (columnNames.Contains("OrderId"))
orderId = reader.GetOrdinal("OrderId");
while (reader.Read())
yield return new BEContractB2CService
{
//..................
Order = new BEOrder
{ Id = orderId == _noOrdinal ?
Guid.Empty : reader.GetGuid(orderId)
},
//............................
答案 0 :(得分:6)
这两种方法是完全不同的,所以它取决于你后来要对我所说的结果做什么。
例如:
第一种情况要求数据读取器保持打开状态直到读取结果,第二种情况不需要。那么你要持有这个结果多长时间,并且你想让数据阅读器保持打开状态。
如果您肯定要读取数据,那么第一种情况就不那么高效,但如果您经常不这样做,可能性能会更高,特别是如果有大量数据的话。
第一个案例的结果只能读取/迭代/搜索一次。然后可以多次存储和搜索第二种情况。
如果你有大量的数据,那么第一种情况可以这样使用,你不需要一次性将所有数据都带入内存。但这又取决于你在调用方法中对IEnumerable的处理方式。
修改强> 鉴于您的用例,这些方法可能与任何给定的“良好”度量相当。表不会有很多列,使用.Contains可确保每次都读取数据。就个人而言,我会坚持使用数组方法,因为它只是因为它是一种更简单的方法。
代码的下一行是什么......是否在寻找不同的列名?如果是这样,第二种情况是唯一的出路。
答案 1 :(得分:3)
关于理由我的头脑:数组版本意味着你必须花时间建立数组。大多数代码的客户端可能不一定需要特定的数组。大多数情况下,我发现,大多数代码只是迭代它,在这种情况下,为什么浪费时间构建一个你从未真正需要的数组(或列表作为替代)。
答案 2 :(得分:2)
第一个是懒惰的。也就是说,在迭代枚举之前不会对代码进行求值,因为你使用闭包它会运行代码直到它产生一个值,然后将控制权转回调用代码,直到你通过MoveNext
迭代到下一个值。另外,对于linq,您可以通过调用第一个然后调用ToArray
来实现第二个。您可能希望这样做的原因是为了确保在进行调用时获取数据,而不是在迭代时获取数据,以防数值在两者之间发生变化。
答案 3 :(得分:2)
一个优点与内存消耗有关。如果FieldCount是100万,那么后者需要分配一个包含100万个条目的数组,而前者则不需要。
这个好处取决于方法的消耗方式。例如,如果您逐个处理文件列表,则无需事先知道所有文件。