我正在编写一个类,它封装了使用ADO.NET从数据库中检索数据的复杂性。
private void Read<T>(Action<T> action) where T : class, new() {
var matches = new LinkedList<KeyValuePair<int, PropertyInfo>>();
// Read the current result set's metadata.
using (DataTable schema = this.reader.GetSchemaTable()) {
DataRowCollection fields = schema.Rows;
// Retrieve the target type's properties.
// This is functionally equivalent to typeof(T).GetProperties(), but
// previously retrieved PropertyInfo[]s are memoized for efficiency.
var properties = ReflectionHelper.GetProperties(typeof(T));
// Attempt to match the target type's columns...
foreach (PropertyInfo property in properties) {
string name = property.Name;
Type type = property.PropertyType;
// ... with the current result set's fields...
foreach (DataRow field in fields) {
// ... according to their names and types.
if ((string)field["ColumnName"] == name && field["DataType"] == type) {
// Store all successful matches in memory.
matches.AddLast(new KeyValuePair<int, PropertyInfo>((int)field["ColumnOrdinal"], property));
fields.Remove(field);
break;
}
}
}
}
// For each row, create an instance of the target type and set its
// properties to the row's values for their matched fields.
while (this.reader.Read()) {
T result = new T();
foreach (var match in matches)
match.Value.SetValue(result, this.reader[match.Key], null);
action(result);
}
// Go to the next result set.
this.reader.NextResult();
}关于该方法的正确性,不幸的是,我现在无法测试它的正确性,我有以下问题:
IDataReader从两个或多个结果集检索数据时,IDataReader.GetSchemaTable是返回所有结果集的元数据,还是仅返回与当前结果集对应的元数据?IDataReader.GetSchemaTable检索的列序号,与索引器IDataReader[int]使用的序数相等吗?如果没有,有没有办法将前者映射到后者?关于该方法的效率,我有以下问题:
DataRowCollection的底层数据结构是什么?即使这个问题不能回答eb,至少使用DataRowCollection从DataRowCollection中删除DataRow的渐近计算复杂性是多少?至于该方法明显的丑陋之处,我有以下问题:
是否有任何方法可以检索特定的元数据(例如,列的序号、名称和类型),而不是完整的模式表,从IDataReader
(string)field["ColumnName"] == name中的string?.NET如何比较碰巧包含对string的引用到string变量的object变量:通过引用值还是内部数据值?(当我有疑问时,我更愿意错误地站在正确性的一边,这样的转换;但是,当能够消除所有的疑问时,我更愿意这样做。)
KeyValuePair<int, PropertyInfo>s来表示匹配的字段和属性对,但这些对并不是实际的键值对。它们只是普通的2元组。但是,.NET框架的2.0版本并不提供元组数据类型,而且,如果我要创建自己的专用元组,我仍然不知道在哪里声明它。在C++中,最自然的位置将在方法中。但这是C#,方法中的类型定义是非法的。我该怎么办?处理使用定义上不最合适的类型(KeyValuePair<int, PropertyInfo>)或无法声明最适合的类型的不优雅?发布于 2011-07-08 18:40:27
我可以回答以下几个问题:
A2)是的,GetSchemaTable中的列序号与索引器使用的列序号相同。
B1)我不确定,但这并不重要,因为如果您在foreach中枚举时从DataRowCollection中删除它,就会抛出它。如果我是你,我会做一个字段或属性的哈希表来帮助匹配它们,而不是担心这个线性搜索和删除。
编辑:I是错的,这是一个谎言--正如爱德华多在下面指出的那样,它不会抛出。但是如果你认为你可能有超过几十个属性的类型的话,它还是有点慢的。
( C2)是的,这是必要的,否则它会通过参考进行比较。
C3)无论如何,我都倾向于使用KeyValuePair。
发布于 2011-07-08 18:47:09
至于A1,我相信在IDataReader.NextResult()被启用之前,GetSchemaTable只会返回当前结果集的信息。
然后,当NextResult()被启用时,您将不得不再次执行一个GetSchemaTable来获取有关当前结果集的信息。
HTH。
https://stackoverflow.com/questions/6628816
复制相似问题