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