Прежде всего, позвольте мне извиниться, если название не имеет смысла. Мне трудно понять, что я делаю, не говоря уже о возможности использовать правильные слова для описания того, что я делаю.
Я создаю общий класс сетки, в котором я определяю столбцы комбинацией выражений header / linq:
public class Column<T>
{
public string Header { get; set; }
public Func<T, string> ValueExpression { get; set; }
}
Использование:
Columns = new List<Column<Employee>>
{
new Column<Employee> {Header = "Employee Id", ValueExpression = e => e.EmployeeID.ToString()},
new Column<Employee> {Header = "Name", ValueExpression = e => e.FirstName + " " + e.LastName},
new Column<Employee> {Header = "Employee Birthday Year", ValueExpression = e => e.BirthDate.HasValue ? e.BirthDate.Value.Year.ToString() : ""}
},
Я хочу проецировать выражение ValueExpression (Func<T, string>
) на IQueryable «сотрудников»:
var db = new NorthwindDataContext();
var employees = db.Employees.Select(e => e);
Я могу заставить это работать, извлекая IEnumerable<IEnumerable<string>>
из сотрудников (список списков строк, используемых в моих представлениях), как это:
var elementsList = employees.ToPagedList(PageIndex, PageSize);
var elementStringList = elementsList.ToStringList(Columns.Select(c => c.ValueExpression).ToArray());
Не обращайте внимания на материал PagedList, он не имеет значения и примерно такой же, как ToList ();
Вот метод расширения ToStringList ():
public static IEnumerable<IEnumerable<string>> ToStringList<T>(this IPagedList<T> enumerable, params Func<T, string>[] fields)
{
foreach (var element in enumerable)
yield return element.ToStringList(fields);
}
private static IEnumerable<string> ToStringList<T>(this T element, params Func<T, string>[] fields)
{
foreach (var field in fields)
yield return field(element);
}
Проблема состоит в том, что этот подход включает выполнение IQueryable перед указанием полей, которые должны быть возвращены.
В результате следующий запрос выполняется где-то по пути:
SELECT [t0].[EmployeeID], [t0].[LastName], [t0].[FirstName], [t0].[Title], [t0].[TitleOfCourtesy], [t0].[BirthDate], [t0].[HireDate], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[HomePhone], [t0].[Extension], [t0].[Photo], [t0].[Notes], [t0].[ReportsTo], [t0].[PhotoPath]
FROM [dbo].[Employees] AS [t0]
Как вы могли догадаться, нежелательно извлекать ВСЕ поля из таблицы Сотрудники.
Я ищу способ каким-то образом создать метод расширения для сотрудников IQueryable, в котором я могу передать список функций (членов столбца "ValueExpression") и "построить" новый IQuerable таким образом, который будет выполнить SQL, который просто извлекает необходимые поля из базы данных.
Итак, я ищу что-то вроде этого:
IQueryable employees = employees.SelectByExpressions(Columns.Select(c => c.ValueExpression).ToArray());
Заранее спасибо.