Как упростить вызов метода расширения Linq с помощью отражения?

Фон:

У меня есть веб-служба, которая возвращает строки в таблице (с именем таблицы, предоставленным в качестве параметра )с идентификаторами, превышающими определенный идентификатор (, также предоставленный в качестве параметра ). Мы предполагаем, что идентификаторы являются последовательными.

Я использую Linq to SQL для взаимодействия с базой данных, поэтому я хочу вернуть новые строки как:

List

Поскольку мы знаем только имя таблицы во время выполнения, я не могу использовать Linq в обычном режиме, что значительно усложняет ситуацию.

Вопрос:

Код ниже (, и он работает ). Как я могу упростить это? Это кажется слишком сложным.

private object GetUpdateList(string tableName, int Id, DataClassesDataContext db)
{
    PropertyInfo pi = db.GetType().GetProperty(tableName);

    var table = pi.GetValue(db, null);

    // Get type of object within the table.
    Type genericType = table.GetType().GetGenericArguments()[0];

    // The Where method lives on the Enumerable type in System.Linq
    var whereMethods = typeof(System.Linq.Enumerable)
       .GetMethods(BindingFlags.Static | BindingFlags.Public)
       .Where(mi => mi.Name == "Where");

    // There are actually 2 where methods - we want the one with 2 parameters
    MethodInfo whereMethod = null;
    foreach (var methodInfo in whereMethods)
    {
        var paramType = methodInfo.GetParameters()[1].ParameterType;
        if (paramType.GetGenericArguments().Count() == 2)
        {
            // we are looking for  Func, the other has 3
            whereMethod = methodInfo;
            break;
        }
    }

    Func 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 });
}

// Build lambda expression for use in Linq
private static Func BuildEqFuncFor(string prop, object val)
{
    // We know we are comparing integers here so cast them.
    // There is probably a more general solution.
    return t => (int)t.GetType().InvokeMember(prop, BindingFlags.GetProperty, null, t, null) > (int)val;
}

Чтобы найти это решение, мне пришлось сослаться на следующие вопросы:

6
задан Community 23 May 2017 в 10:30
поделиться