如何将一个数据reader转换为动态查询结果
How to convert a data reader to dynamic query results
我有一个视图,通常从 WebMatrix 查询(IEnumerable<dynamic>
数据类型)获取查询结果,并在 table:
中显示结果
@model MySite.Models.Entity
@foreach(var row in Model.Data)
{
<tr>
@foreach (var column in row.Columns)
{
<td>@column<span>:</span> @row[column]</td>
}
</tr>
}
这是我查询数据库的模型:
public class Entity
{
public dynamic Data {get; set; }
public Entity(String table)
{
if (table == "User" || table == "Group)
{
WebMatrix.Data.Database db = new WebMatrix.Data.Database();
db.Open(ConString);
Data = db.Query("SELECT * FROM " + table);
}
else
{
using (OdbcConnection con = ne4w OdbcConnection(ConString))
{
OdbcCommand com = new OdbcCommand("Select * From " + table);
command.CommandType = System.Data.CommandType.Text;
connection.Open();
OdbcDataReader reader = command.ExecuteReader();
以下是我通过阅读其他各种帖子尝试过的所有不同方法:
// Atempt 1
Data = reader;
// Error in view, 'Invalid attempt to call FieldCount when reader is closed' (on 'var row `in` Model.Data')
// Atempt 2
Data = reader.Cast<dynamic>;
// Error: 'Cannot convert method group "Cast" to non-delegate type "dynamic". Did you intend to invoke the method?
// Atempt 3
Data = reader.Cast<IEnumerable<dynamic>>;
// Error same as Atempt 2
// Atempt 4
Data = reader.Cast<IEnumerable<string>>;
// Error same as Atempt 2
}
}
}
}
我正在寻找将 reader 对象转换为 IEnumerable<dynamic>
对象的最佳方法。
请注意这是一个简化的示例,虽然这两种查询类型的原因并不明显,但它们在我的代码中是必需的。
尝试循环 reader 结果:
OdbcDataReader reader = command.ExecuteReader();
while(reader.Read())
{
var item = reader["yourField"].ToString();
}
看起来您只是想将对象设置为 command.ExecuteReader() 的未执行 IQueriable 结果;
您缺少基本的 C# 语法。
Data = reader;
// You cant do this. You have to loop the reader to get the values from it.
// If you simply assign reader object itself as the data you wont be
// able to get data once the reader or connection is closed.
// The reader is typically closed in the method.
Data = reader.Cast<dynamic>;
// You should call the Cast method. And preferably execute the resulting query.
// As of now you're merely assigning method reference to a variable
// which is not what you want.
// Also bear in mind that, as I said before there's no real benefit in casting to dynamic
Data = reader.Cast<IEnumerable<dynamic>>;
// Cast method itself returns an IEnumerable.
// You dont have to cast individual rows to IEnumerable
Data = reader.Cast<IEnumerable<string>>;
// Meaningless I believe.
// The data you get from database is not always strings
你犯的主要错误是没有调用方法。这就是你想要的:
Data = reader.Cast<IDataRecord>().ToList();
^^ // notice the opening and closing parentheses
根据更容易处理的内容(例如,在前端显示),您可以通过多种方式解决此问题。
Return条数据记录。
public IEnumerable<IDataRecord> SelectDataRecord()
{
....
using (var reader = cmd.ExecuteReader())
foreach (IDataRecord record in reader as IEnumerable)
yield return record; //yield return to keep the reader open
}
Return 扩展对象。 也许这就是你想要的?
public IEnumerable<dynamic> SelectDynamic()
{
....
using (var reader = cmd.ExecuteReader())
{
var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();
foreach (IDataRecord record in reader as IEnumerable)
{
var expando = new ExpandoObject() as IDictionary<string, object>;
foreach (var name in names)
expando[name] = record[name];
yield return expando;
}
}
}
Return 属性 包的序列
public IEnumerable<Dictionary<string, object>> SelectDictionary()
{
....
using (var reader = cmd.ExecuteReader())
{
var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();
foreach (IDataRecord record in reader as IEnumerable)
yield return names.ToDictionary(n => n, n => record[n]);
}
}
Return 普通对象数组的序列
public IEnumerable<List<object>> SelectObjectArray()
{
....
using (var reader = cmd.ExecuteReader())
{
var indices = Enumerable.Range(0, reader.FieldCount).ToList();
foreach (IDataRecord record in reader as IEnumerable)
yield return indices.Select(i => record[i]).ToList();
}
}
Return 数据行
public IEnumerable<DataRow> SelectDataRow()
{
....
using (var reader = cmd.ExecuteReader())
{
var table = new DataTable();
table.BeginLoadData();
table.Load(reader);
table.EndLoadData();
return table.AsEnumerable(); // in assembly: System.Data.DataSetExtensions
}
}
最后但同样重要的是,如果有帮助,您可以 return 强类型序列而无需任何手动管道。您可以使用表达式树在 运行 时间编译代码。请参阅 this,例如
我有一个视图,通常从 WebMatrix 查询(IEnumerable<dynamic>
数据类型)获取查询结果,并在 table:
@model MySite.Models.Entity
@foreach(var row in Model.Data)
{
<tr>
@foreach (var column in row.Columns)
{
<td>@column<span>:</span> @row[column]</td>
}
</tr>
}
这是我查询数据库的模型:
public class Entity
{
public dynamic Data {get; set; }
public Entity(String table)
{
if (table == "User" || table == "Group)
{
WebMatrix.Data.Database db = new WebMatrix.Data.Database();
db.Open(ConString);
Data = db.Query("SELECT * FROM " + table);
}
else
{
using (OdbcConnection con = ne4w OdbcConnection(ConString))
{
OdbcCommand com = new OdbcCommand("Select * From " + table);
command.CommandType = System.Data.CommandType.Text;
connection.Open();
OdbcDataReader reader = command.ExecuteReader();
以下是我通过阅读其他各种帖子尝试过的所有不同方法:
// Atempt 1
Data = reader;
// Error in view, 'Invalid attempt to call FieldCount when reader is closed' (on 'var row `in` Model.Data')
// Atempt 2
Data = reader.Cast<dynamic>;
// Error: 'Cannot convert method group "Cast" to non-delegate type "dynamic". Did you intend to invoke the method?
// Atempt 3
Data = reader.Cast<IEnumerable<dynamic>>;
// Error same as Atempt 2
// Atempt 4
Data = reader.Cast<IEnumerable<string>>;
// Error same as Atempt 2
}
}
}
}
我正在寻找将 reader 对象转换为 IEnumerable<dynamic>
对象的最佳方法。
请注意这是一个简化的示例,虽然这两种查询类型的原因并不明显,但它们在我的代码中是必需的。
尝试循环 reader 结果:
OdbcDataReader reader = command.ExecuteReader();
while(reader.Read())
{
var item = reader["yourField"].ToString();
}
看起来您只是想将对象设置为 command.ExecuteReader() 的未执行 IQueriable 结果;
您缺少基本的 C# 语法。
Data = reader;
// You cant do this. You have to loop the reader to get the values from it.
// If you simply assign reader object itself as the data you wont be
// able to get data once the reader or connection is closed.
// The reader is typically closed in the method.
Data = reader.Cast<dynamic>;
// You should call the Cast method. And preferably execute the resulting query.
// As of now you're merely assigning method reference to a variable
// which is not what you want.
// Also bear in mind that, as I said before there's no real benefit in casting to dynamic
Data = reader.Cast<IEnumerable<dynamic>>;
// Cast method itself returns an IEnumerable.
// You dont have to cast individual rows to IEnumerable
Data = reader.Cast<IEnumerable<string>>;
// Meaningless I believe.
// The data you get from database is not always strings
你犯的主要错误是没有调用方法。这就是你想要的:
Data = reader.Cast<IDataRecord>().ToList();
^^ // notice the opening and closing parentheses
根据更容易处理的内容(例如,在前端显示),您可以通过多种方式解决此问题。
Return条数据记录。
public IEnumerable<IDataRecord> SelectDataRecord() { .... using (var reader = cmd.ExecuteReader()) foreach (IDataRecord record in reader as IEnumerable) yield return record; //yield return to keep the reader open }
Return 扩展对象。 也许这就是你想要的?
public IEnumerable<dynamic> SelectDynamic() { .... using (var reader = cmd.ExecuteReader()) { var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList(); foreach (IDataRecord record in reader as IEnumerable) { var expando = new ExpandoObject() as IDictionary<string, object>; foreach (var name in names) expando[name] = record[name]; yield return expando; } } }
Return 属性 包的序列
public IEnumerable<Dictionary<string, object>> SelectDictionary() { .... using (var reader = cmd.ExecuteReader()) { var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList(); foreach (IDataRecord record in reader as IEnumerable) yield return names.ToDictionary(n => n, n => record[n]); } }
Return 普通对象数组的序列
public IEnumerable<List<object>> SelectObjectArray() { .... using (var reader = cmd.ExecuteReader()) { var indices = Enumerable.Range(0, reader.FieldCount).ToList(); foreach (IDataRecord record in reader as IEnumerable) yield return indices.Select(i => record[i]).ToList(); } }
Return 数据行
public IEnumerable<DataRow> SelectDataRow() { .... using (var reader = cmd.ExecuteReader()) { var table = new DataTable(); table.BeginLoadData(); table.Load(reader); table.EndLoadData(); return table.AsEnumerable(); // in assembly: System.Data.DataSetExtensions } }
最后但同样重要的是,如果有帮助,您可以 return 强类型序列而无需任何手动管道。您可以使用表达式树在 运行 时间编译代码。请参阅 this,例如