LINQ To SQL Dynamic Select - PullRequest
       18

LINQ To SQL Dynamic Select

5 голосов
/ 07 июня 2010

Может кто-нибудь показать мне, как указать, какие столбцы я хотел бы вернуть во время выполнения из оператора LINQ To SQL?

Я разрешаю пользователю выбирать элементы в контрольном списке, представляющем столбцы, которые он хотел бы отобразить в виде сетки, которая связана с результатами запроса L2S.

Я могу динамически генерировать предложение WHERE, но не могу сделать то же самое с частью SELECT. Вот образец:

var query = from log in context.Logs select log;
                query = query.Where(Log => Log.Timestamp > CustomReport.ReportDateStart);
                query = query.Where(Log => Log.Timestamp < CustomReport.ReportDateEnd);
                query = query.Where(Log => Log.ProcessName == CustomReport.ProcessName);

                foreach (Pair filter in CustomReport.ExtColsToFilter)
                {
                    sExtFilters = "<key>" + filter.First + "</key><value>" + filter.Second + "</value>";
                    query = query.Where(Log => Log.FormattedMessage.Contains(sExtFilters));
                }

Ответы [ 2 ]

3 голосов
/ 07 июня 2010

Короткий ответ: не .

Метод должен иметь известный, определенный тип возвращаемого значения. Этот тип может быть System.Object, но тогда вам придется использовать много уродливого кода отражения, чтобы получить членов. И в этом случае вам также придется использовать много уродливого отражения кода дерева выражений для генерации возвращаемого значения.

Если вы пытаетесь динамически генерировать столбцы на стороне пользовательского интерфейса - прекратите это делать. Определите столбцы во время разработки, а затем просто отобразите / скройте столбцы, которые вам действительно нужны / которые хочет видеть пользователь. Пусть ваш запрос вернет все столбцы, которые могут быть видны.

Если вы не заметите серьезной проблемы с производительностью, выбирая все столбцы данных (в этом случае у вас, вероятно, возникают проблемы с индексами на уровне базы данных, которые не покрываются), вам будет гораздо лучше с этим подходом. Вполне нормально генерировать предикаты и порядок сортировки динамически, но вы действительно не хотите делать это со списком вывода.


Некоторые комментарии заставили меня серьезно задуматься о том, был ли я прав в своем предположении, что динамический список вывода на самом деле возможен , и я пришел к выводу, что это так, несмотря на то, что это опасно Плавание против текущей идеи. Чтобы выполнить этот трюк, вам необходимо:

  1. Создать новый тип, используя Reflection.Emit .
  2. Создание дерева выражений, которое инициализирует его, используя Expression.MemberInit .
  3. Скомпилируйте выражение и передайте его методу Select.
  4. Верните слабо набранный System.Object из вашего метода и используйте Reflection для доступа к членам по имени.

Это не та вещь, которую я когда-либо хотел бы видеть в рабочем коде, но у вас это есть - это возможно.

1 голос
/ 07 июня 2010

Вам не нужно делать это на уровне запросов (это было бы довольно сложно в любом случае, поскольку вам нужно было бы динамически создавать тип во время выполнения) ... Это гораздо проще сделать в самом GridView, явно объявив столбцы, которые вы хотите отобразить.

...