Я использую LINQ-to-Entities. Используя следующий запрос:
var x = from u in context.Users select new { u.Id, u.Name };
То, что только выбирает столбцы Id
и Name
. Отлично.
Я пытаюсь создать хранилище, которое можно передать этому new { u.Id, u.Name}
в качестве параметра, позволяющего клиенту выбирать, какие столбцы используются в операторе SELECT.
Я пытаюсь использовать «свободный» интерфейс с моим хранилищем вместо синтаксиса запроса. По сути, последний вызов - преобразовать IQueryable в IList и выполнить код. Я посмотрел на библиотеку DynamicExpressions, но я не совсем уверен, что это путь, по которому я хочу пойти для этого. Это можно сделать с помощью синтаксиса запроса, но не с помощью свободного интерфейса?
Редактировать: Извините, я должен был упомянуть, что все запросы инкапсулированы внутри хранилища. Так, например, я хочу иметь возможность выставить метод, подобный следующему:
public void Project(Expression<Func<TEntity, TEntity>> fields)
{
this.Projection = fields;
}
Так что назвать это будет так:
using (DBContext context = new DBContext())
{
IUserRepository repo = new UserRepository(context);
repo.Project(u => new { u.Id, u.Name });
repo.GetById(100);
}
Внутри GetById
будет что-то вроде ctx.Users.Where(u => u.Id == id).Select(this.Projection)
.
Таким образом, возвращаемые столбцы могут быть выбраны вызывающим кодом. Причина этого в том, что, возможно, я хочу вернуть объект User, но, возможно, мне нужны только Id и Name (и, следовательно, возвращать меньше данных по сети).
Проблема в том, что я, очевидно, не могу преобразовать анонимный тип в User. Было бы здорово, если бы я мог сделать что-то вроде:
repo.Project(u => new User() { Id = u.Id, Name = u.Name });
Что означало бы, что мне не нужно создавать анонимный тип. РЕДАКТИРОВАТЬ: Хорошо, похоже, это работает ТОЛЬКО, если тип, который возвращается является POCO ... тьфу.
EDIT2 : Возможно, мне придется пойти на подход DLINQ. Я думаю, что Expression<Func<TEntity, object>>
(для использования анонимного типа), а затем использовать отражение, чтобы получить список свойств. Затем с помощью DLINQ создайте строковое выражение. Единственным недостатком является то, что я на самом деле не хочу использовать DLINQ, поскольку он добавляет немного накладных расходов (Reflection.Emit и т.