The data that has the SQL logged against it was a table and object called PersonalDetail and the SQL was stored in a column/property called LookUpStatement. I wanted to get an Ilist<> of the data results that LookUpStatement returns when executed. The key thing I wanted to achieve was that the new method would return the IList<> strongly typed. So in the case of the industry data I would have IList<Industry> returned by it or for AgeGroup an IList<AgeGroup>.
The whole passing and returning of dynamic types has been something I have wanted to master for some time. After some extensive searching and no single article telling me exactly what I needed I managed to pile it all together and ended with this...
Calling and using it:
//Get the personal detail row that is required // The Load method loads a specifc row from the database // In this instance, row 1 LookUpStatement will select all industires (e.g. SELECT * FROM [Industry]) PersonalDetail personalDetail = PersonalDetail.Load(1); //Get the industries as an IList from the personal detail object IList<Industry> industries = personalDetail.LookUpData<List<Indstry>>();
Note that the LookUpData call is made using a List<> and not an IList<>.The code itself:
public class PersonalDetail
{
public LookUpStatement
{
get; set;
}
//Other properties, constructor, etc...
public T LookUpData<T>()
{
if (!typeof(T).Name.StartsWith("List"))
throw new ArgumentException("The generic pass type must be a List<>");
//Create a typed instance of the required List
T os = (T)Activator.CreateInstance(typeof(T));
//Get the base object propertype. e.g. Industry
Type propType = typeof(T).GetProperty("Item").PropertyType;
//Get the data as a DataSet
DataSet ds = _DB.GetDataSet(this.LookUpStatement);
//Iterate the data
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
//Get the data row
DataRow dr = ds.Tables[0].Rows[i];
//Use relfection to execute the Add method of the dynmaic List
//Then use relfection to execute the LogItem method of the base object
// Logitem converts the data row into the base object. e.g. Industry
os.GetType().GetMethod("Add").Invoke(
os,
new object[] {
propType.GetMethod("LogItem").Invoke(null, new object[] { dr })
}
);
}
}
}
The comments in the code should hopefully give an indication of how it works. Working out the T os = (T)Activator.CreateInstance(typeof(T)); took a while as defining the os object as IList<object> just wasn't working. Got there in the end though :)
No comments:
Post a Comment