Reputation: 1661
I have the name of a stored procedure stored in a database (and a couple of views). At run time I query the database and then run the needed query. Since I don't know the field names of the query nor do I have a known object to store the results to I use a dynamic variable
dynamic results = Respository.GetTableContents();
// not exactly the code but it conveys the point
The table would have an unknown number of fields, but for this example the field names are
Id, FirstName, Lastname //(this is what the table would be returning)
// Normally stored to a list of the model type
List<Users> resultsFromTable = ...
The resulting dynamic data can be accessed by
foreach(var r in result)
{
string name = r.FirstName + " " + r.LastName;
//.... Do something with the code, etc.
}
That is great if you know the property names. I don't know the property names.
How do I access the data of the dynamic variable without knowing the property name?
My main goal would be to use this in the view (razor).
Maybe I have approached the problem wrong and there is a better way. Any thoughts?
Upvotes: 0
Views: 1842
Reputation: 32561
An alternative would be to use System.Reflection
. Try this:
foreach (var r in results)
{
string name, trimmedName = "";
if (r.GetType() == typeof(ExpandoObject))
{
name = ((IDictionary<string,object>)r).ToList()
.Aggregate<KeyValuePair<string,object>, string>("", (s, p) =>
{
return s + " " + p.Value;
});
trimmedName = name.Trim();
}
else
{
PropertyInfo[] ps = r.GetType().GetProperties();
name = ps.Aggregate<PropertyInfo, string>("", (s, p) =>
{
return s + " " + p.GetValue(r);
});
trimmedName = name.Trim();
}
// use the trimmedName
Console.WriteLine(trimmedName);
}
[EDIT] Based on @pwas' suggestio, here's an version of he code with an improved Cyclomatic Complexity:
foreach (var r in results)
{
ProcessResult(r);
}
Where ProcessResult
has 2 overloads:
static void ProcessResult(ExpandoObject r)
{
string name, trimmedName = "";
name = ((IDictionary<string, object>)r).ToList()
.Aggregate<KeyValuePair<string, object>, string>("", (s, p) =>
{
return s + " " + p.Value;
});
trimmedName = name.Trim();
FurtherProcess(trimmedName);
}
static void ProcessResult(object r)
{
string name, trimmedName = "";
PropertyInfo[] ps = r.GetType().GetProperties();
name = ps.Aggregate<PropertyInfo, string>("", (s, p) =>
{
return s + " " + p.GetValue(r);
});
FurtherProcess(trimmedName);
}
private static void FurtherProcess(string trimmedName)
{
Console.WriteLine(trimmedName);
}
Here is the improvement:
Type Maintainability Cyclomatic
Index Complexity
Program 54 24
// After code optimization
Program 69 16
Upvotes: 1