Hopefully you have read my other posts on Enterprise Library 5 DAAB for a bit of background as this post is going to be very quick and to the point:
- Database Accessors in Enterprise Library 5 DAAB - Database.ExecuteSprocAccessor
- EnterpriseLibraryContainer and IServiceLocator in Enterprise Library 5
- Database.ExecuteSqlStringAccessor and LINQ in Enterprise Library 5 DAAB
- IRowMapper via MapBuilder and Mapping Properties in EntLib 5 DAAB
IResultSetMapper
As mentioned before with regards to IRowMapper in Enterprise Library 5 DAAB, there are times when you need a bit more control over how to map the results being returned from the database to individual entities and/or the entire resultset.
When you need to control the binding to individual entities, IRowMapper is your savior. IRowMapper helps you map an individual IDataRecord to the entity to which it binds. When you need control at the ResultSet level, IResultSetMapper is your guy. IResultSetMapper works at the IDataReader level and allows you to control looping through the IDataReader as well as custom databinding of each IDataRecord if you so choose.
Using the same example from before with IRowMapper, below is an example of creating a custom IResultSetMapper, MyResultSetMapper, that loops through the entire resultset and returns IEnumerable<Contact>. Note that in this case I don’t really need control at the IDataReader level, but I did it for the sake of illustration.
class Program
{
static void Main(string[] args)
{
var database = EnterpriseLibraryContainer.Current.GetInstance<Database>();
var contacts = database.ExecuteSqlStringAccessor<Contact>
("SELECT Id, Email FROM Contacts", new MyResultSetMapper());
foreach (var contact in contacts)
Console.WriteLine(string.Format("{0}: {1}", contact.Id, contact.Email));
Console.ReadLine();
}
}
public class MyResultSetMapper : IResultSetMapper<Contact>
{
public IEnumerable<Contact> MapSet(System.Data.IDataReader reader)
{
var contacts = new List<Contact>();
while (reader.Read())
contacts.Add(new Contact { Id = reader.GetInt32(0), Email = reader.GetString(1)});
return contacts;
}
}
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
There is a part of me that wants to use an iterator from within MyResultSetMapper as shown below, but I do not like to use yield return for deferred execution from within an open database connection, which is an expensive resource. Opinions may vary.
public class MyResultSetMapper : IResultSetMapper<Contact>
{
public IEnumerable<Contact> MapSet(System.Data.IDataReader reader)
{
while (reader.Read())
yield return new Contact { Id = reader.GetInt32(0), Email = reader.GetString(1)});
}
}
The results of each entity are the same as when we used a custom IRowMapper in the last Enterprise Library 5 DAAB Tutorial:

Conclusion
Although I am sure I will write other Enterprise Library 5 DAAB Tutorials in the future, I think we hit most of the interesting changes. Time to move on to other changes in Enterprise Library 5.
Hope this helps.

Comments