Применить выражение linq объекта к списку элементов, где этот объект является собственностью элемента (Wrapper) - PullRequest
3 голосов
/ 25 ноября 2011

Мне нужно иметь возможность применить выражение свойства к оболочке этого свойства, ниже приведен пример;список чисел и список номеров оберток, где выражение [где числа четные]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace ExpressionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            /* Expression */
            Expression<Func<int, bool>> expression = item => item % 2 == 0;


            /* List */
            IList<int> items = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                items.Add(i);
            }
            IEnumerable<int> evenNumbers = items.Where(expression.Compile());
            foreach (int number in evenNumbers)
            {
                Console.WriteLine(number.ToString());
            }


            /* Wrappers List */
            // How to apply expression to the porpery 'Number'?
            IList<Wrapper> wrappers = new List<Wrapper>();
            for (int i = 0; i < 10; i++)
            {
                wrappers.Add(new Wrapper { Number = i });
            }
            IEnumerable<int> evenWrappedNumbers = ????; 
            foreach (Wrapper wrappedNumber in evenWrappedNumbers)
            {
                Console.WriteLine(wrappedNumber.ToString());
            }
        }
    }

    public class Wrapper
    {
        public int Number;
    }
}

Ответы [ 2 ]

7 голосов
/ 25 ноября 2011

Это должно сработать:

Func<int, bool> predicate = expression.Compile();
IEnumerable<Wrapper> evenWrappedNumbers = wrappers.Where(w => predicate(w.Number));

Или, если вы действительно хотите IEnumerable<int>

Func<int, bool> predicate = expression.Compile();
IEnumerable<int> evenWrappedNumbers = wrappers.Where(w => predicate(w.Number)).Select(w => w.Number);

Редактировать: с тех пор, как вы узнали, что NHibernate используется, вот еще один возможныйрешение.Пожалуйста, имейте в виду, я не использую NHibernate и имею ограниченный опыт работы с деревьями выражений.Но, тем не менее, это, мы надеемся, позволит NHibernate разобрать дерево выражений в SQL.

Сначала определите метод расширения в статическом классе следующим образом:

    public static IQueryable<T> Where<T, TProperty>(this IQueryable<T> source,
        Expression<Func<T, TProperty>> propertySelector,
        Expression<Func<TProperty, bool>> predicate)
    {
        MemberExpression member = propertySelector.Body as MemberExpression;

        if (member == null)
            throw new ArgumentException("Must be a property selector", "propertySelector");

        string propertyName = member.Member.Name;

        // The input type
        ParameterExpression propertyParameter = Expression.Parameter(typeof(T));

        // The property on that type
        MemberExpression itemProperty = Expression.Property(propertyParameter, propertyName);

        // Invoke the specified predicate with the property from the input type
        InvocationExpression invokeExpression = Expression.Invoke(predicate, itemProperty);

        // The lambda expression for use with Linq
        Expression<Func<T, bool>> finalExpression = Expression.Lambda<Func<T, bool>>(invokeExpression, propertyParameter);

        return source.Where(finalExpression);
    }

Затем этот метод расширения можетиспользовать так:

    IEnumerable<Wrapper> evenWrappedNumbers = wrappers.Where(w => w.Number, expression);

Как я уже сказал, у меня нет опыта работы с NHibernate, но, надеюсь, он сможет проанализировать это дерево выражений и преобразовать его в SQL.

0 голосов
/ 25 ноября 2011

Вот несколько способов, которые не используют выражения.Полагаю, вы хотите решение Луказоида.

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