标题似乎有些不专业,但是相信好多人都知道是怎么回事,开发中最常见的数据操作就是DataReader=>IList<T> 了,当然使用ORM框架的话就不用为这个烦恼了。在Google上没找到一个完整的解决方案,但是自己总结了网上说的,写了一个还算满意的方案。
通常我们会有一个实体类,这个实体类只有属性与数据库字段对应,例如:
(截图不完整)
如何让DataReader转换呢?我写了一个扩展方法(由于是重构代码),扩展实体类使之增加一个方法
以扩展上图的QuestionAnswerInfo为例:
上图中CreateQusetionAnswerInfo方法之所以能做到通用,也就是说不管查询任意组合的某些字段都能正确赋值关键是IDataRecord的
public static T Field<T>(this IDataRecord record, string fieldName) 的扩展方法,它可以保证没有查询的字段和查询了但是返回时NULL的字段对应实体类的属性
设置为默认值
该方法的实现如下:
public static T Field<T>(this IDataRecord record, string fieldName)
{
T fieldValue = default(T);
for (int i = 0; i < record.FieldCount; i++)
{
if (string.Equals(record.GetName(i), fieldName,StringComparison.OrdinalIgnoreCase))
{
if (record[i] != DBNull.Value)
{
fieldValue = (T)record[fieldName];
}
}
}
return fieldValue;
}
呵呵,这个IDataRecord的扩展有点像Linq to DataSet中得到字段值的操作了。另外IDataReader是继承了IDataRecord所以这个扩展方法IDataReader也可以使用。
有个上面的两个扩展方法之后,还需要一个对IDataReader的扩展,代码如下:
public static IEnumerable<T> GetEnumerator<T>(this IDataReader reader,
Func<IDataRecord, T> generator)
{
while (reader.Read())
yield return generator(reader);
}
实现都很简单,下面看看如何使用(代码片段):
using (IDataReader dr = _db.ExecuteReader(command))
{
questionAnswerList = dr.GetEnumerator<QuestionAnswerInfo>(new QuestionAnswerInfo().CreateQuestionAnswerInfo).ToList();
}
使用时注意:一定要注意Select语句中查询字段名称一定要和对用实体类的属性名称一样。
补充:图2中QuestionAnswerInfo实体类的扩展CreateQuestionAnswerInfo方法的实现书写起来也是比较费事,可以自己写一个代码生成的方法生产代码
具体到我这里代码如下:
public string CodeDump<T>()
{
string result = string.Empty;
System.Reflection.PropertyInfo[] properties = typeof(T).GetProperties();
foreach (System.Reflection.PropertyInfo item in properties)
{
result += string.Format("{0} = record.Field<{1}>(\"{0}\"),", item.Name, item.PropertyType.FullName);
}
return result;
}
使用也很简单呀,弄一个aspx页面,在页面上放在一个TextBox控件,Page_Load方法中调用上面的方法给TextBox赋值就可以了
TextBox1.Text = CodeDump<QusetionItemInfo>();然后把TextBox中的值复制过去,编辑器自动帮你排好版了。
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛