Скажем, у меня есть эти свойства, которые переопределены в производном классе.
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
Типы аргументов не совпадают