Объединение выражений выбора одного и того же типа ввода

Скажем, у меня есть эти свойства, которые переопределены в производном классе.

protected virtual Expression<Func<TEntity, long>> GetIDExpr { get; }
protected virtual Expression<Func<TEntity, string>> GetNameExpr { get; }
protected virtual Expression<Func<TEntity, long>> GetValueExpr { get; }

Теперь скажем, у меня есть этот класс

public class MyData
{
    public long ID { get; set; }
    public string Name { get; set; }
    public long Value { get; set; }
}

Теперь, в базовом классе, как мне создать Expression<Func<TEntity, MyData>>, который при вызове будет заполнять каждое поле и позволит мне создать метод, возвращающий IEnumerable<MyData>?

Я бы не хотел использовать Invoke, так как я бы хотел, чтобы эти 3 поля были выбраны из базы данных.

Примечание. В этом примере рассматривайте каждое свойство так, как если бы при каждом вызове оно возвращало один и тот же экземпляр выражения, а не создавало каждый раз новый экземпляр.

Изменить:

Вот моя попытка, которая не работает:

public IEnumerable<MyData> GetAllData(IQueryable<TEntity> table) {
    ParameterExpression parameter = Expression.Parameter(typeof(TEntity), "obj");

    List<MemberBinding> bindings = new List<MemberBinding>  {
        Expression.Bind(typeof(MyData).GetProperty("ID"), GetIDExpr.Body),
        Expression.Bind(typeof(MyData).GetProperty("Name"), GetNameExpr.Body),
        Expression.Bind(typeof(MyData).GetProperty("Value"), GetValueExpr.Body),
    };

  var selector = Expression.MemberInit(Expression.New(typeof(MyData).GetConstructor(Type.EmptyTypes)), bindings);

  var getBar = Expression.Lambda<Func<TEntity, MyData>>(selector, parameter);

  return table.Select(getBar);
}

Здесь я получаю ArgumentException при выполнении запроса, говоря

Параметр obj не был связан в указанном выражении запроса LINQ to Entities.

Я предполагаю, что это означает, что использование .Body для выражения значения не будет работать, поскольку параметра больше нет. Однако, если я не использую .Body, я получаю исключение в методе .Bind

Типы аргументов не совпадают


person Connell    schedule 21.03.2012    source источник


Ответы (1)


Я не знаю способа собрать дерево выражений из других деревьев выражений в лямбда-выражении, поэтому я думаю, что вам придется строить дерево программно. В этой статье MSDN (Как использовать деревья выражений для создания динамических запросов) показано, как использовать API дерева выражений для построения дерева выражений.

В этом случае вам понадобится выражение new, за которым следуют три назначения свойств; Я не думаю, что вы можете сделать это в дереве выражений. Вы можете обойти это, создав конструктор, который присваивает свойства.

person phoog    schedule 21.03.2012
comment
В LINQ to Entities поддерживаются только конструкторы без параметров. Я знал, что это произойдет. Есть ли шанс, что я могу комбинировать операторы Expression.Assign? - person Connell; 21.03.2012