Помогите с Linq и Generics. Использование GetValue внутри запроса - PullRequest
3 голосов
/ 28 декабря 2010

Я пытаюсь создать функцию, которая добавляет предложение 'where' к запросу на основе свойства и значения.Это очень простая версия моей функции.

Private Function simplified(ByVal query As IQueryable(Of T), ByVal PValue As Long, ByVal p As PropertyInfo) As ObjectQuery(Of T)

    query = query.Where(Function(c) DirectCast(p.GetValue(c, Nothing), Long) = PValue)
    Dim t = query.ToList 'this line is only for testing, and here is the error raise
    Return query

End Function

Сообщение об ошибке: LINQ to Entities не распознает метод System.Object CompareObjectEqual (System.Object, System.Object, Boolean).и этот метод не может быть переведен в выражение хранилища.

Похоже, вы не можете использовать GetValue внутри запроса linq.Могу ли я добиться этого другим способом?

Опубликовать свой ответ в C # / VB.Выберите тот, который заставляет вас чувствовать себя более комфортно.

Спасибо

РЕДАКТИРОВАТЬ : я также пробовал этот код с теми же результатами

Private Function simplified2(ByVal query As IQueryable(Of T))

    query = From q In query
            Where q.GetType.GetProperty("Id").GetValue(q, Nothing).Equals(1)
            Select q
    Dim t = query.ToList
    Return query
End Function

Ответы [ 2 ]

6 голосов
/ 28 декабря 2010

Вам необходимо преобразовать код в дерево выражений.

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace WindowsFormsApplication1
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            using (var context = new NorthwindEntities())
            {
                IQueryable<Customer> query = context.Customers;
                query = Simplified<Customer>(query, "CustomerID", "ALFKI");
                var list = query.ToList();
            }
        }

        static IQueryable<T> Simplified<T>(IQueryable<T> query, string propertyName, string propertyValue)
        {
            PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName);
            return Simplified<T>(query, propertyInfo, propertyValue);
        }

        static IQueryable<T> Simplified<T>(IQueryable<T> query, PropertyInfo propertyInfo, string propertyValue)
        {
            ParameterExpression e = Expression.Parameter(typeof(T), "e");
            MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo);
            ConstantExpression c = Expression.Constant(propertyValue, propertyValue.GetType());
            BinaryExpression b = Expression.Equal(m, c);

            Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(b, e);
            return query.Where(lambda);
        }
    }
}
0 голосов
/ 28 декабря 2010

Вы пытались вытянуть DirectCast и поразмышлять о параметре лямбда? Как то так:

query.Where(Function(c) _
    c.GetType().GetProperty(p, GetType("Int64")).GetValue(c, Nothing) = PValue)

Я не уверен, что вы можете делать такие вещи в лямбде, но это стоит попробовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...