Как использовать значение из выражения LINQ средства доступа к свойству в выражении LINQ Contains?

В настоящее время у меня есть выражение LINQ для средства доступа к свойству, которое обращается к свойству объекта. Теперь мне нужно создать выражение LINQ, которое будет оценивать предикат, чтобы увидеть, содержится ли результат метода доступа к свойству в списке.

Я видел, что в большинстве случаев такие вещи выполняются с использованием статических методов в Expression, однако в Expression нет доступных в качестве статических методов Contains или In, поэтому я не уверен, что делать дальше.

// A data object
internal class PersonDAL
{
    public int Age ( get; set; }
}

// A business object
public class Person
{
    private PersonDAL root { get; set; }

    public static Expression<Func<PersonDAL, int>> AgeExpression
    {
        get
        {
            return (root) => (root.Age);
        }
    }
}

Теперь я хочу иметь возможность проверить, содержится ли значение AgeExpression в списке возрастов. Обычно это было бы чем-то вроде написания выражения, чтобы увидеть, содержит ли список значений значение, которое я хочу проверить, но я не вижу, как передать результат выражения в качестве значения для поиска.

Чтобы немного прояснить, я пытаюсь выяснить, как взять запрашиваемый объект, содержащий все лица, и получить только те лица, в которых неизвестное выражение оценивается как истинное на основе значения из другого выражения. В моем примере выражение неизвестного средства доступа смотрит на возраст человека, и ему необходимо иметь возможность оценить, содержится ли оно в другом списке приемлемых возрастов.


person AJ Henderson    schedule 23.04.2013    source источник
comment
LINQ to Entities? LINQ to Objects? LINQ to XML?   -  person dtb    schedule 23.04.2013
comment
@dtb - в настоящее время базовый DAL представляет собой более старую версию шаблонов Codesmith PLINQO. Я вручную создал средства доступа к свойствам в объектах BOL, которые указывают на объекты DAL, создаваемые PLINQO.   -  person AJ Henderson    schedule 23.04.2013
comment
Как бы вы составили запрос без динамического выражения?   -  person dtb    schedule 23.04.2013
comment
Статическое значение AgeExpression не сработает. Ему нужен доступ к переменной экземпляра. Должен ли он быть нестатическим или мне что-то еще не хватает?   -  person Shlomo    schedule 23.04.2013
comment
@Shlomo - это выражение-аксессуар. Это функция, которая загружает конкретный экземпляр PersonDal и оценивает свойство в этом экземпляре.   -  person AJ Henderson    schedule 23.04.2013


Ответы (2)


Я не уверен, почему вы используете выражения. Я не понимаю, что вы от них выиграете. Но если вы измените подпись AgeExpression на Expression<Func<PersonDAL, int>>, вы можете скомпилировать ее и выполнить:

void Main()
{
    var pDal = new PersonDAL { Age = 3 };

    var ageFunc = Person.AgeExpression.Compile();
    var age = ageFunc(pDal);
    // age is 3
}

// Define other methods and classes here

// A data object
public class PersonDAL
{
    public int Age { get; set; }
}

// A business object
public class Person
{
    public Person(PersonDAL dal)
    {
        this.dal = dal;
    }

    private PersonDAL dal { get; set; }

    public static Expression<Func<PersonDAL, int>> AgeExpression
    {
        get
        {
            return (root) => (root.Age);
        }
    }
}
person Shlomo    schedule 23.04.2013
comment
Основная причина - попытка создать LINQ-совместимую структуру фильтров. Все, что на самом деле будет известно во время выполнения, - это выражения, которые определяют, как разрешить конкретное значение, и затем мне придется использовать это значение в фильтре. Однако компиляция и выполнение могут быть тем, что мне нужно, поэтому я попробую и посмотрю, где я могу добраться. - person AJ Henderson; 23.04.2013
comment
Да, к тому же, у меня там уже был Func, я просто пропустил его при переносе в пример. Что я не уверен, так это то, что я бы передал, чтобы значение передавалось ему, когда к нему обращаются в другом моем выражении. Чтобы дать более полный пример, скажем, я выбираю список лиц, где их возраст находится в списке из 10, 20 и 30. Я могу добавить возраст в список и сделать AgeList.Contains (AgeAccessorFunc (??) ), но мне нужен способ связать мой выбор Person с Contains и аксессуаром. - person AJ Henderson; 23.04.2013
comment
И я предполагаю, что AgeList - это некая форма IQueryable? Итак, запрос будет выглядеть примерно так: Persons.Where (p = ›AgeList.Contains (p.Age))? - person Shlomo; 23.04.2013
comment
да что-то подобное. Я думаю, что на самом деле это функция Age, принимающая p в качестве параметра. Совершенно уверен, что это работает для конкретного примера, но я не уверен в том, как это собрать, если есть дополнительные критерии. Я думаю, что это, вероятно, приводит к другому вопросу. - person AJ Henderson; 23.04.2013

Эта проблема меня тоже сильно сбила с толку ... помните, что вы можете получить доступ к локальным переменным в ваших LINQ / лямбда-выражениях: поэтому простой .where(x => x.value == AgeExpression) должен указать вам в правильном направлении

person Izzy    schedule 23.04.2013