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

本文介绍了一种使用反射技术简化数据库查询结果映射到对象的过程,通过反射获取对象属性并自动填充从数据库读取的数据,提高了代码复用性和开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在与数据库的交互中,查询数据是经常要做的事情,每一组数据,我们都要去手写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);
            }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值