日期:2014-05-17  浏览次数:20561 次

利用反射,DataReader填充泛型集合List<T>
网上找的代码,稍微改了一下,请问这样做是否会有效率问题,或者,还有没有其它更好、更方便的方法填充List<T>?(ORM除外)
C# code

        public static List<T> ToList<T>(IDataReader reader)
        {

            //实例化一个List<>泛型集合
            List<T> DataList = new List<T>();
            while (reader.Read())
            {
                T RowInstance = Activator.CreateInstance<T>();//动态创建数据实体对象

                //通过反射取得对象所有的Property
                foreach (PropertyInfo Property in typeof(T).GetProperties())
                {
                    foreach (BindingFieldAttribute FieldAttr in Property.GetCustomAttributes(typeof(BindingFieldAttribute), true))
                    {
                        try
                        {
                            //取得当前数据库字段的顺序
                            int Ordinal = reader.GetOrdinal(FieldAttr.FieldName);
                            if (reader.GetValue(Ordinal) != DBNull.Value)
                            {
                                //将DataReader读取出来的数据填充到对象实体的属性里
                                Property.SetValue(RowInstance, Convert.ChangeType(reader.GetValue(Ordinal), Property.PropertyType), null);
                            }
                        }
                        catch
                        {
                            break;
                        }
                    }
                }
                DataList.Add(RowInstance);
            }
            return DataList;
        }

        //自定义的Attribute,用于与数据库字段进行绑定
        public class BindingFieldAttribute : System.Attribute
        {
            public string FieldName { get; set; }
        }



------解决方案--------------------
public IList <T> GetList <T>(DataTable table)
{
IList <T> list = new List <T>();
T t = default(T);
PropertyInfo[] propertypes = null;
string tempName = string.Empty;
foreach (DataRow row in table.Rows)
{
t = Activator.CreateInstance <T>();
propertypes = t.GetType().GetProperties();
foreach (PropertyInfo pro in propertypes)
{
tempName = pro.Name;
if (table.Columns.Contains(tempName))
{
object value = row[tempName];
pro.SetValue(t, value, null);
}
}
list.Add(t);
}
return list;
}

tb.OfType<TableRow>().Select(row=>
new YourType{Field1=(string)row["field1"],Field2=(int)row["field2"]}).ToList();
 
------解决方案--------------------
使用PDF.NET框架来查询数据,不需要反射,现在已经开源了,可以看看。
------解决方案--------------------
C# code
 T RowInstance = Activator.CreateInstance<T>();//动态创建数据实体对象

这个东西 可以有第2种方式 就是用 泛型的约束了

例如:
void Test<T>(IDataReader reader) where T:new
{
T t = new T();
}

------解决方案--------------------
使用Emit(ILGenerator)将DataReader自动填充到list<T>,可以参考http://blog.csdn.net/qldsrx/article/details/7452346里面的代码,Emit绑定List<T>,加上缓存的话,效率有时候比硬编码速度都快,不过有个缺点,Emit有些难学懂。
Emit例子百度搜索DynamicBuilder<T>、AutoMapper等。
------解决方案--------------------
http://topic.csdn.net/u/20120830/15/568c5362-5b21-48c0-941e-b77cc442ff98.html
http://topic.csdn.net/u/20120919/15/927d7808-fa3f-4e48-8e56-5043c2d9974e.html
这是我发布的两个帖子,还是非常感谢青龙白虎前辈的帮忙的。