- EF 6, .NET 4.51
I am trying to build a generic helper class that will help me "translate" each of the result sets into a type safe class as described here Handle multiple result from a stored procedure with SqlQuery
For my solution I want to pass the following to my helper class (MultiResultsetsHelper):
- Generic Return Type
- ObjectContext
- DataReader
- List of class types in order of the result sets coming back
and then have the helper class do the heavy lifting of populating 1. Below is the code so far:
Classes For Result
public class Set1ReturnDto
{
public int CruiseCount { get; set; }
public string DisplayText { get; set; }
public int DisplayValue { get; set; }
}
public class Set2ReturnDto
{
public string DepartingFrom { get; set; }
public string Port_Code { get; set; }
}
public class DummyReturnDto
{
public DummyReturnDto()
{
Set1 = new List<Set1ReturnDto>();
Set2 = new List<Set2ReturnDto>();
}
public List<Set1ReturnDto> Set1 { get; set; }
public List<Set2ReturnDto> Set2 { get; set; }
}
Low Level Database Call
public static DummyReturnDto DonoUspGetSideBarList(DbContext aDbContext, out int aProcResult)
{
SqlParameter procResultParam = new SqlParameter { ParameterName = "@procResult", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output };
DbCommand dbCommand = aDbContext.Database.Connection.CreateCommand();
dbCommand.Parameters.Add(procResultParam);
dbCommand.CommandText = "EXEC @procResult = [dbo].[usp_GetSideBarList] ";
dbCommand.Transaction = aDbContext.Database.CurrentTransaction.UnderlyingTransaction;
DbDataReader reader = dbCommand.ExecuteReader();
aProcResult = -1;
// Drop down to the wrapped `ObjectContext` to get access to the `Translate` method
ObjectContext objectContext = ((IObjectContextAdapter)aDbContext).ObjectContext;
List<Type> containedDtos = new List<Type>
{
typeof (List<Set1ReturnDto>),
typeof (List<Set1ReturnDto>)
};
return MultiResultsetsHelper.Process<DummyReturnDto>(reader, objectContext, containedDtos);
}
The resulting datasets returned are:
Helper Class
public static class MultiResultsetsHelper
{
/// <summary>
/// Given a data reader that contains multiple result sets, use the supplied object context to serialise the
/// rows of data in the result set into our property.
/// </summary>
/// <typeparam name="T">Type of the containing object that contains all the various result sets.</typeparam>
/// <param name="aDbReader">Database reader that contains all the result sets returned from the database.</param>
/// <param name="aObjectContext">Data context associated with the data reader.</param>
/// <param name="aContainedDataSetReturnedTypes">
/// List of types in order of which the result sets are contained within the
/// data reader. We will serilize sequentially each result set the data reader contains
/// </param>
/// <returns>Retuns an object representing all the result sets returned by the data reader.</returns>
public static T Process<T>(DbDataReader aDbReader, ObjectContext aObjectContext, List<Type> aContainedDataSetReturnedTypes) where T : new()
{
//What we will be returning
T result = new T();
for (int datasetNdx = 0; datasetNdx < aContainedDataSetReturnedTypes.Count; datasetNdx++)
{
//Advance the reader if we are not looking at the first dataset
if (datasetNdx != 0)
aDbReader.NextResult();
//Get the property we are going to be updating based on the type of the class we will be filling
PropertyInfo propertyInfo = typeof (T).GetProperties().Single(p => p.PropertyType == aContainedDataSetReturnedTypes[datasetNdx]);
//Now get the object context to deserialize what is in the resultset into our type
var valueForProperty = aObjectContext.Translate <aContainedDataSetReturnedTypes[datasetNdx]> (aDbReader);
//Finally we update the property with the type safe information
propertyInfo.SetValue(result, valueForProperty, null);
}
return result;
}
}
However currently I cannot get this to compile.
Error 2 Operator '<' cannot be applied to operands of type 'method group' and 'System.Type'
Can someone help out? Ultimately it has to do with how we use reflection and the passed in aContainedDataSetReturnedTypes. I am happy to change things around as long as it is still easy to call MultiResultsetsHelper.Process<>()