2

Я хотел бы иметь некоторую гибкость и предоставить некоторый интерфейс, чтобы указать список столбцов, который должен быть включен в окончательный выбор динамически.Entity Framework - получить только конкретные столбцы, указанные динамически из списка

Например для этой таблицы

public class Person 
    { 
     [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity), Key()] 
     public int Id { get; set; } 

     [Required] 
     public string FirstName { get; set; } 

     [Required] 
     public string LastName { get; set; } 

     public string Address { get; set; } 

     ... 
    } 

Я хочу, чтобы в одном случае

persons.Select(p => new { FirstName = p.FirstName, LastName = p.LastName }).ToList(); 

, но в другом я хочу иметь

persons.Select(p => new { FirstName = p.FirstName, LastName = p.LastName, Address = p.Address }).ToList(); 

в третьем случае я нужно что-то еще ... Итак, я думал, что было бы неплохо иметь какой-то гибкий механизм, который позволил бы указать список col umns для извлечения.

Любые идеи, как я могу это сделать?

Я читал немного о выражениях LINQ и у меня есть какое-то чувство, что это правильный путь, но не понимаю, как осуществить это еще ...

+1

Вы пробовали эти два выражения? – DFord

+0

Это способ сделать это –

+1

@DFord, что случилось с этими двумя выражениями? –

ответ

1

Если включить пакет NuGet System.Linq.Dynamic его довольно проста:

var columns = new [] { "FirstName", "LastName" }; 
var selectText = "new (" + string.Join(", ", columns) + ")"; 
var result = Users.AsQueryable().Select(selectText); 

Или для безопасности типа

var columns = new Expression<Func<User, object>> [] { x => x.FirstName, x => x.Surname }; 
var selectText = "new (" + string.Join(", ", columns.Select(x => ((MemberExpression)x.Body).Member.Name)) + ")"; 
var result = Users.AsQueryable().Select(selectText); 

Это превращает выражение в строку для библиотеки, которая превратит их обратно, так что ISN Оптимальный подход, но стоимость, вероятно, будет незначительной по сравнению с запросом базы данных.

Вы можете сделать это, построив выражения, но библиотека сделает все для вас.

+0

Привет, Mant101, спасибо, что указал мне на System.Linq.Dynamic ... Я попытался добавить его в мое решение, но, к сожалению, я уже использую EntityFramework.Extended, и у этого также есть расширение Select внутри того же пространства System.Linq.Dynamic, поэтому они находятся в конфликте друг с другом. Я пробовал метод из EntityFramework.Extended, но он вызывает исключение ... продолжит копать в этом направлении. Еще раз спасибо ... –

+0

Если у вас есть конфликт, вы можете использовать стандартную номенклатуру name.methodname для доступа к методу расширения как обычный статический метод. – Mant101

0

В основном это правильный способ, которым вы это делаете. Вы можете сделать это чуть более комфортно и безопасно, используя классы как «Модели» для ваших данных. В принципе, создайте другой класс Person с любыми полями таблицы или только теми, которые вам нужны в этом «личном». Выполнение этого вместо создания безымянных объектов и записи их в список дает вам большую гибкость, поскольку вы можете добавить другие методы, которые преобразуют данные в этом классе.

Вы также можете добавить к этому классу разные конструкторы в зависимости от того, какие поля вы хотите инициализировать. Как это:

var modelPersons = persons.Select(p => new ModelPerson(p.FirstName, p.LastName)).ToList(); 

Если вы пишете конструктор для каждой инициализации вам нужно, вы будете иметь многоразовый и короткий код при запросе. Конечно, вы все еще можете использовать инициализатор объекта, как это:

var modelPersons = persons.Select(p => new ModelPerson { 
    FirstName = p.FirstName 
    LastName = p.LastName 
}).ToList(); 

Который является до тех пор, как тот, который вы в курсе, но это лучше использовать объект, который вы можете определить сами, добавлять методы, формат данных и т.д. Но все вместе вы используете правильный подход.

0

Чтобы расширить ответ Mant101. Вы можете решить проблему с дублирующимся пространством имен, используя extern alias. См. Также this answer на вопрос SO.