C# 利用反射将数据从SqlDataReader对象中,赋值给相应的Model

news/2024/5/19 6:40:03 标签: 反射, C#

在与数据库的交互中,查询数据是经常要做的事情,每一组数据,我们都要去手写modle.属性 = dr["字段名"],这样去赋值,虽然各表的字段名,字段属性都不相同,但是回归本质,其实是同一个操作,于是,我便想到了用反射的方法,基于Model层,获取Model的全部属性,进行赋值,便可适用大部分的查询数据操作!
        public static TEntity MapEntity<TEntity>(SqlDataReader reader) where TEntity : class, new()
        {
            try
            {
                var properties = typeof(TEntity).GetProperties();
                var entity = new TEntity();
                foreach (var propertie in properties)
                {
                    if (propertie.CanWrite)//判断属性是否可写
                    {
                        try
                        {
                            var index = reader.GetOrdinal(propertie.Name.Replace("_", ""));//列序号
                            var data = reader.GetValue(index);//指定列值
                            if (data != DBNull.Value)
                            {
                                if (propertie.PropertyType.IsGenericType && propertie.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                                {
                                    propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType.GetGenericArguments()[0]), null);
                                }
                                else
                                {
                                    propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType), null);
                                }
                            }
                        }
                        catch (IndexOutOfRangeException ex)
                        {
                            continue;
                        }
                    }
                }
                return entity;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

调用
            while (dr.Read())
            {
                mod = Class1.MapEntity<stuModel>(dr);
                list.Add(mod);
            }

当然,利用反射性能上,就会和之前的方法相距甚远,于是,我们可以把反射出来的属性值集合参数化,避免多次反射,其实结果都是一样的,在C#编程中,面向对象的思想很重要,减少代码冗余,增加代码重用率,参数化是经常用到的思想;

参数化后:
        public static TEntity MapEntity<TEntity>(SqlDataReader reader, PropertyInfo[] properties) where TEntity : class, new()
        {
            try
            {
                // properties 为了避免多次反射,将其参数化,在C#编程中,应时刻有着面向对象的思想,而不是面向过程
                //var properties = typeof(TEntity).GetProperties();
                var entity = new TEntity();
                foreach (var propertie in properties)
                {
                    if (propertie.CanWrite)//判断属性是否可写
                    {
                        try
                        {
                            var index = reader.GetOrdinal(propertie.Name.Replace("_", ""));//列序号
                            var data = reader.GetValue(index);//指定列值
                            if (data != DBNull.Value)
                            {
                                if (propertie.PropertyType.IsGenericType && propertie.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                                {
                                    propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType.GetGenericArguments()[0]), null);
                                }
                                else
                                {
                                    propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType), null);
                                }
                            }
                        }
                        catch (IndexOutOfRangeException ex)
                        {
                            continue;
                        }
                    }
                }
                return entity;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

参数化后调用:
            var properties = typeof(stuModel).GetProperties();
            while (dr.Read())
            {
                mod = Class1.MapEntity<stuModel>(dr,properties);
               list.Add(mod);
            }


http://www.niftyadmin.cn/n/1637269.html

相关文章

typedef void fun(void)

转自https://zhidao.baidu.com/question/268132515.html?qblrelate_question_0&wordtypedef%20void%28%2AFuncPtr%29%28%29 typedef void (*fun)(void); 首先请看void (*fun)(void) 这里定义了一个函数指针fun&#xff0c;fun指向一个参数为void&#xff0c;返回值为void的…

分享一个老式卡带机风格的HTML5 Audio播放器实现

日期&#xff1a;2012-7-31 来源&#xff1a;GBin1.com 在线演示 本地下载 如果你不知道什么是卡带机的话&#xff0c;恭喜你&#xff0c;你真的非常太年轻&#xff0c;作为八&#xff0c;九十年代播放音乐必备的设备&#xff0c;对于我们这些70&#xff0c;80后的朋友来说会…

C#.NET底层 List 集合循环添加对象(如:list.add(model)),为什么会出现整个list集合都是一样的数据?

先考考大家&#xff0c;这段代码&#xff0c;有没有问题&#xff1f;stuModel mod new stuModel();while (dr.Read()){mod.DDID dr["DDID"].ToString();mod.CPfenlei dr["CPfenlei"].ToString();mod.CPguige dr["CPguige"].ToString();mod.C…

poj 3159 Candies 差分约束

poj 3159 Candies 差分约束 //poj 3159 Candies//差分约束 //不了解差分约束的可以看看这个 //http://hi.baidu.com/qinning199/item/65d270215bb365182a0f1c07 //这题是我的第一题差分约束//题意&#xff1a; //有n个孩子分糖果&#xff0c;m个孩子的要求&#xff0c;没个要求…

C++复制构造函数和赋值符的区别

转自http://blog.csdn.net/randyjiawenjie/article/details/6666937 今天做C primer的习题&#xff0c;被复制构造函数和赋值符的区别弄晕了。简单地说&#xff0c;有一道题目如下描述&#xff1a; class t1; class t2 t1; 我先看见有一个等号&#xff0c;以为就是赋值符来…

为什么我不做金蝶二次开发了,个人的感受!

我2017年8月&#xff0c;刚来深圳&#xff0c;同月便进了一家从事金蝶二开的公司&#xff0c;公司很小&#xff0c;我离职可能有公司的原因在里面&#xff0c;但是此文&#xff0c;我想客观得来说明&#xff0c;为什么不做金蝶二开了&#xff01;直入主题&#xff1a;金蝶二开&…

jni c++调用java

1. jvm.dll要在环境变量PATH&#xff0c;例如 ...;D:\java\sdk6\jre\bin\client 2. 需要的jar要合并为一个 BbyteCcharDdoubleFfloatIintJlongSshortVvoidZbooleanLfully-qualified-classfully qualified class[typearray of type>(argument types)return typemethod type. …

个人职业生涯第01号总结 2016.8-2017.6实习总结

我于2016年8月进入业界&#xff0c;以实习生的身份&#xff0c;至今已快两年&#xff0c;两年中&#xff0c;完成了身份转变&#xff0c;实现了个人能力的提升&#xff0c;亦产生了一点点的体会&#xff1b;2016年8月&#xff0c;我参加了实习&#xff0c;在上海&#xff0c;拿…