您的位置:首页 > 移动开发

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

2016-10-19 15:17 791 查看
在数据库访问的时候,很多情况下从数据库返回的是一个结果集(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 =
9c4b
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;
});
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐