Spring.Net——使用对象映射(RowMapper)返回数据库查询到的结果集

在数据库访问的时候,很多情况下从数据库返回的是一个结果集(List),怎么样把它转换为我们在C#代码中定义的实体类型?

Spring.Net定义了三组接口和委托用于回调,开发人员需要自己实现或定义这些回调方法

(1)IResultSetExtractor/ResultSetExtractorDelegate:传递一个IDataReader对象,开发人员可以利用该对象迭代数据并返回结果对象。

(2)IRowCallback/RowCallbackDelegate:传递一个IDataReader对象,可用于处理当前行。返回值为void,因此在实现IRowCallback接口时一般将类实现为有状态的(按:也就是说实现类需要定义自己的字段来保存回调的结果),在使用匿名委托时,一般用本地变量来保存回调的结果。

(3)IRowMapper/RowMapperDelegate:传递一个IDataReader对象,用以处理当前行并返回一个对应于当前行的对象。

我们这次主要讲解一下第三种.

IRowMapper可以让开发人员专注于如何将结果集中的一行映射为一个对象。框架会负责使用IDataReader进行迭代并创建一个IList来保存结果对象.

Dao层的代码如下:

 

//必须要继承AdoDaoSupport,
//AdoDaoSupport中集成了所有连接数据库,执行访问数据库,关闭数据的所有操作
public class PersonDao:AdoDaoSupport
{ 
    public IList<Person> GetPersonInfoDetailsByPersonId(string personId)
        {
            //定义返回 的对象
            IList<Person> result = new List<Person>();
            //定义用于装载参数的集合
            IDbParameters parameters = AdoTemplate.CreateDbParameters();
            //添加参数
            parameters.AddWithValue("PersonId", new Guid(personId));
            //使用QueryWithRowMapper方法访问数据库,返回结果集
            result = AdoTemplate.QueryWithRowMapper<Person>(
                CommandType.StoredProcedure,"SP_GetPersonInfoByPersonId", new PersonMapper<Person>(), parameters);
            return result;
        }
}

PersonMapper的定义如下:

 

逐行将数据转换为实体类

 

 public class PersonMapper<T> : IRowMapper<T> where T : Person, new()
    {
        T IRowMapper<T>.MapRow(IDataReader dataReader, int rowNum)
        {
            T view = new T();
            if (DataReaderRowFilter.RowFilter(dataReader, "PersonId"))
                view.PersonId = dataReader.GetValueOrDefault<Guid>("PersonId");
            if (DataReaderRowFilter.RowFilter(dataReader, "PersonName"))
                view.PersonName = dataReader.GetValueOrDefault<String>("PersonName");
            if (DataReaderRowFilter.RowFilter(dataReader, "Age"))
                view.Age = dataReader.GetValueOrDefault<int>("Age");

            return view;
        }
    }

DataReaderRowFilter.RowFilter定义如下:

 

判断DataReader中是否有某列

 

 public class DataReaderRowFilter
    {
        public static bool RowFilter(IDataReader dataReader, string columnName)
        {
            dataReader.GetSchemaTable().DefaultView.RowFilter = string.Format("ColumnName='{0}'", columnName);
            return dataReader.GetSchemaTable().DefaultView.Count > 0;
        }
    }

GetValueOrDefault定义如下:

 

 

 public static T GetValueOrDefault<T>(this IDataReader reader, string columnName)
        {
            int index = reader.GetOrdinal(columnName);
            T returnValue = default(T);
            if (!reader.IsDBNull(index))
            {
                returnValue = (T)Convert.ChangeType(reader[columnName], typeof(T));

                //returnValue = (T)reader[columnName];
            }
            return returnValue;
        }


如果映射的逻辑比较少,并且需要使用访问本地变量的时候,使用委托会更加方便(参考官方文档):

 

 

 public virtual IList<Customer> GetCustomersWithDelegate()
        {
            return AdoTemplate.QueryWithRowMapperDelegate<Customer>(CommandType.Text, cmdText,
                        delegate(IDataReader dataReader, int rowNum)
                            {
                                Customer customer = new Customer();
                                customer.Address = dataReader.GetString(0);
                                customer.City = dataReader.GetString(1);
                                customer.CompanyName = dataReader.GetString(2);
                                customer.ContactName = dataReader.GetString(3);
                                customer.ContactTitle = dataReader.GetString(4);
                                customer.Country = dataReader.GetString(5);
                                customer.Fax = dataReader.GetString(6);
                                customer.Id = dataReader.GetString(7);
                                customer.Phone = dataReader.GetString(8);
                                customer.PostalCode = dataReader.GetString(9);
                                customer.Region = dataReader.GetString(10);
                                return customer;
                            });
        }

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值