Monday, May 5, 2008

Generics Examples - Generating instances with two methods or how to simplify the DAL

In this delivery two methods to generate instances or collections of our entities, simplifying therefore the code of our DAL (traditionally composed by a great amount of methods and mappings “field to field” from tables to objects). Once collected the data using a DataReader, with these methods is possible to obtain a single entity instance or a strong typed collection of instances.

The Methods


// A single instance
public static void FillEntity<T>(T instance, IDataRecord datarecord)
{
Type instanceType = instance.GetType();
for (int i = 0; i < datarecord.FieldCount; i++)
{
if (datarecord[i] != DBNull.Value)
{
string propName = datarecord.GetName(i);
PropertyInfo propInfo = instanceType.GetProperty(propName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (propInfo != null)
{
propInfo.SetValue(instance, datarecord[propInfo.Name], null);
}
}
}
}

// A instance collection
public static List<T> FillEntities<T>(IDataReader dr)
{
List<T> entities = new List<T>();
while (dr.Read())
{
T instance = Activator.CreateInstance<T>();
Utils.FillEntity<T>(instance, dr);
entities.Add(instance);
}
return entities;
}

Using the methods



// A Single Instance
public static UserInfo UserGetById(string userid)
{
UserInfo userInfo = new UserInfo();
Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetStoredProcCommand("usergetbyid");
db.AddInParameter(dbCommand, "userid", DbType.String, userid);
IDataReader idr = db.ExecuteReader(dbCommand);
if (idr.Read())
{
Utils.FillEntity<UserInfo>(userInfo, idr);
}
return userInfo;
}

// A instance collection
public static List<OrderInfo> GetOrders(int customerid)
{
Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetStoredProcCommand("getorders");
db.AddInParameter(dbCommand, "customerid", DbType.Int32, customerid);
return Utils.FillEntities<OrderInfo>(db.ExecuteReader(dbCommand));
}

2 comments:

Anonymous said...

Hi mister, great blog.

two points:

what about performance using Reflection ?

Fill entity when property is nullable.


thanks in advance.

Please, send me email enrique.prados@a-e.es

Martín Olivares said...

1) Fill entity works fine with nullable fields.
2) About performance, there is a penalty introduced by the use of reflection that can be reduced caching the entity properties. Anyway, performance in an application is a wide topic that involves more than only the use of Reflection. Using Reflection judiciously can provide many advantages.