将 SqlDataReader 转换为 linq 表达式
Convert SqlDataReader to linq expression
在查看互联网上有关如何使用 SqlDataReader
的示例时,我发现如下内容:
var command = new SqlCommand( // initialize with query and connection...
var reader = command.ExecuteReader();
while(reader.Read())
{
var foo = reader["SomeColName"];
// etc
}
我可以使用以下扩展方法吗:
public static IEnumerable<IDataReader> ToEnumerable(this IDataReader reader)
{
while (reader.Read())
yield return reader;
}
为了使用 linq 执行查询?
如果我用下面的扩展方式会不会不好?如果我关心性能,我应该使用第一个实现吗?
我看不出你提议的扩展对你有什么帮助,因为你只得到一个枚举,其中包含每个读取行的 IDataReader
的相同实例。
我不确定是否有什么好的方法可以将 IDataReader
与 LINQ 结合使用,但您可能想要这样的东西:
public static IEnumerable<Dictionary<string, object>> ToEnumerable(this IDataReader reader)
{
while (reader.Read())
{
Dictionary<string, object> result = new Dictionary<string, object>();
for (int column = 0; column < reader.FieldCount; column++)
result.Add(reader.GetName(column), reader.GetValue(column));
yield return result;
}
}
这将 return 一系列字典(每行一个字典),将列名称映射到 "cell" 中的对象。
不幸的是,您失去了类型安全并产生了内存开销。具体实现仍然取决于您真正想要实现的目标。就个人而言,我总是只使用列索引而不是名称。
也就是说,我认为最好的方法仍然是直接使用 IDataReader
来创建 pocos 并将此 pocos 与 LINQ 一起使用:
IEnumerable<string> GetSomeColValue(IDataReader reader)
{
while(reader.Read())
yield return reader.GetString(reader.GetOrdinal("SomeColName"));
}
当然这是一个简化的例子。在实际代码中,我会从 reader 完全读取所有数据,并且 close/dispose reader 实例 在调用 ExecuteReader
的方法中在 return 进行任何操作之前。
您只需将 IEnumerable
转换为 IEnumerable<IDataRecord>
var enumerable = reader.Cast<IDataRecord>();
var col = enumerable.Select(record => record .GetOrdinal("SomeColName"));
在查看互联网上有关如何使用 SqlDataReader
的示例时,我发现如下内容:
var command = new SqlCommand( // initialize with query and connection...
var reader = command.ExecuteReader();
while(reader.Read())
{
var foo = reader["SomeColName"];
// etc
}
我可以使用以下扩展方法吗:
public static IEnumerable<IDataReader> ToEnumerable(this IDataReader reader)
{
while (reader.Read())
yield return reader;
}
为了使用 linq 执行查询?
如果我用下面的扩展方式会不会不好?如果我关心性能,我应该使用第一个实现吗?
我看不出你提议的扩展对你有什么帮助,因为你只得到一个枚举,其中包含每个读取行的 IDataReader
的相同实例。
我不确定是否有什么好的方法可以将 IDataReader
与 LINQ 结合使用,但您可能想要这样的东西:
public static IEnumerable<Dictionary<string, object>> ToEnumerable(this IDataReader reader)
{
while (reader.Read())
{
Dictionary<string, object> result = new Dictionary<string, object>();
for (int column = 0; column < reader.FieldCount; column++)
result.Add(reader.GetName(column), reader.GetValue(column));
yield return result;
}
}
这将 return 一系列字典(每行一个字典),将列名称映射到 "cell" 中的对象。
不幸的是,您失去了类型安全并产生了内存开销。具体实现仍然取决于您真正想要实现的目标。就个人而言,我总是只使用列索引而不是名称。
也就是说,我认为最好的方法仍然是直接使用 IDataReader
来创建 pocos 并将此 pocos 与 LINQ 一起使用:
IEnumerable<string> GetSomeColValue(IDataReader reader)
{
while(reader.Read())
yield return reader.GetString(reader.GetOrdinal("SomeColName"));
}
当然这是一个简化的例子。在实际代码中,我会从 reader 完全读取所有数据,并且 close/dispose reader 实例 在调用 ExecuteReader
的方法中在 return 进行任何操作之前。
您只需将 IEnumerable
转换为 IEnumerable<IDataRecord>
var enumerable = reader.Cast<IDataRecord>();
var col = enumerable.Select(record => record .GetOrdinal("SomeColName"));