Background:
I have a web service that returns rows in a table (table name provided as a parameter), with identifiers that exceed a specific Id (also supplied as a parameter). We assume that identifiers are sequential.
I use Linq for SQL to interact with the database, so I want to return new rows as follows:
List<WhateverObject>
Since we only know the table name at runtime, I cannot use Linq in normal mode, which made things a lot more complicated.
Question:
The code is below (and it works). How can I simplify this? It seems too complicated.
private object GetUpdateList(string tableName, int Id, DataClassesDataContext db)
{
PropertyInfo pi = db.GetType().GetProperty(tableName);
var table = pi.GetValue(db, null);
Type genericType = table.GetType().GetGenericArguments()[0];
var whereMethods = typeof(System.Linq.Enumerable)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "Where");
MethodInfo whereMethod = null;
foreach (var methodInfo in whereMethods)
{
var paramType = methodInfo.GetParameters()[1].ParameterType;
if (paramType.GetGenericArguments().Count() == 2)
{
whereMethod = methodInfo;
break;
}
}
Func<object, bool> IdEquals = BuildEqFuncFor("Id", Id);
whereMethod = whereMethod.MakeGenericMethod(genericType);
var result = whereMethod.Invoke(table, new object[] { table, IdEquals });
MethodInfo toListMethod = typeof(System.Linq.Enumerable).GetMethod("ToList").MakeGenericMethod(genericType);
return toListMethod.Invoke(result, new object[] { result });
}
private static Func<object, bool> BuildEqFuncFor(string prop, object val)
{
return t => (int)t.GetType().InvokeMember(prop, BindingFlags.GetProperty, null, t, null) > (int)val;
}
To come up with this solution, I had to turn to the following questions: