Nano Hash - криптовалюты, майнинг, программирование

Выполнить выражение в другом источнике IQueryable

Есть два класса с одинаковой структурой полей: WebMessage и WebMessageDto.

У меня есть DataGrid, который может работать с обоими классами. И у меня есть служба RIA, которая может предоставить только WebMessageDto, потому что WebMessage имеет свойства навигации и их нельзя сериализовать.

Теперь DataGrid должен запросить метод службы RIA, возвращающий IQueryable<WebMessageDto>. Мне нужно обработать запрос DataGrid и выполнить его в ORM Table<WebMessage>, затем преобразовать результат в тип WebMessageDto и вернуть его в DataGrid.

Я начал реализовывать собственный интерфейс IQueryable и могу обрабатывать выражения.

public class WebMessageQueryContext
{
    // Executes the expression tree that is passed to it. 
    internal static object Execute(Expression expression, bool isEnumerable)
    {
        // DataContext.WebMessages is a ORM table which returns IQueryable<WebMessage>
        List<WebMessage> list = DataContext.WebMessages.Provider.Execute(expression);

        return WebMessageDto.ConvertFrom(list); // returning List<WebMessageDto>
    }
}

Приведенный выше код будет выполнять рекурсивные вызовы этого метода. И я нашел образец Microsoft, где запрашиваемый источник изменяется в ExpressionVisitor, и теперь я меняю исходный код на таблицу ORM.

    protected override Expression VisitConstant(ConstantExpression c)
    {
        if (c.Type == typeof(WebMessageDtoQuerySource<WebMessageDto>))
            return Expression.Constant(DataContext.WebMessages);

        return c;
    }

Я получаю исключение, когда выполняю выражение:

Expression of type 'System.Data.Linq.Table'1[WebMessage]' cannot be used for parameter of type 'System.Linq.IQueryable'1[WebMessageDto]' of method 'Int32 Count[WebMessageDto](System.Linq.IQueryable1[WebMessageDto])'`

Про IQueryableProviders мало информации и что делать не знаю... Кто может ответить, теоретически можно?

20.06.2014

  • Я могу помочь вам с этим провайдером LINQ, но я еще не уверен, что это необходимо. Какой именно статический тип имеет this в приведенном выше коде? Возможно, не IQueryable, а IEnumerable. 20.06.2014
  • Я работаю с devExpress GridControl, и он привязывается к коллекции IQueryable, чтобы обеспечить сортировку/фильтрацию/группировку. Но есть ограничение — GridControl не может работать с сущностями, он может работать только с dtos. 20.06.2014
  • Метод WebMessageDtos загружает все строки базы данных в память, выполняет преобразование и после этого выполняется внешний запрос linq. Мне нужно загрузить в память только необходимые строки и вернуть их как dto. 20.06.2014
  • @usr Я полагаю, что выражение имеет ссылку на исходный IQueryableProvider, который содержит метод Execute, указанный выше. Могу ли я изменить цель выражения на таблицу WebMessages? 20.06.2014
  • Какой источник данных режима сервера вы используете? Концепции режима сервера 20.06.2014
  • Опять же, какой тип this? 21.06.2014
  • @usr this — это ORM DataContext (DevExpress XPO) 23.06.2014
  • @BrianR.Mullin Я использую RiaInstantFeedback. Мои службы RIA должны возвращать WebMessage, но я не могу сгенерировать правильный прокси объекта из-за свойств навигации в классе WebMessage. Поэтому я решил вернуться WebMessageDto 23.06.2014
  • Каков пример запроса, передаваемого службе RIA? 27.06.2014
  • @Justin Может быть просто выбрать _riaService.GetWebMessageDtoQuery().Take(20) 30.06.2014
  • @JesseJames, что вы подразумеваете под приведенным выше кодом, который будет выполнять рекурсивные вызовы этого метода. Почему бы вам не запрашивать сущности и не использовать оператор Cast‹› в IQuereable для преобразования WebMessage в WebMessageDto? Опять же, я могу сказать, что эта проблема не требует использования какого-либо настроенного выражения. 01.07.2014
  • Похоже, вы только меняете источник с WebMessageDto на WebMessage. Любые входные данные завернуты в параметры, которые также необходимо будет изменить. Кроме того, для самих лямбда-выражений потребуется изменить тип вывода. Пример показывает простой пример. Но если он должен принимать любой запрос, вам, возможно, придется реализовать каждый метод ExpressionVisitor, показанный на Инструкции Microsoft 01.07.2014

Ответы:


1

Извините, ребята, я ошибся. Перед редактированием вопроса я написал, что Select применяется к IQueryable перед Where вызывает загрузку всех строк таблицы в память, а затем выполнение оператора Where. Но на самом деле такое поведение было вызвано некорректной реализацией кастомного linq-провайдера.

Когда я использовал datagrid без пользовательского провайдера linq, я упомянул, что Select выполняется после Where, даже если Select применяется до Where.

В моем коде:

public IQueryable<WebMessageDto> Dtos 
{ 
    get { return db.WebMessages.Select(r => new WebMessageDto { Id = r.Id });} 
}

My DataGrid запрашивает этот метод с операторами Where/OrderBy/GroupBy, а преобразование в WebMessageDto происходит после них.

Итак, ответ Алекса Ки также применим.

02.07.2014
  • Рад, что ты разобрался, Джесси Джеймс. 03.07.2014

  • 2

    Вы можете использовать automapper для преобразования между вашими типами.

    Вот руководство по началу работы.

    e.g.

    Mapper.CreateMap<Order, OrderDto>();
    OrderDto dto = Mapper.Map<OrderDto>(order);
    

    РЕДАКТИРОВАТЬ

    Вы можете использовать расширения IQueryable для автоматического сопоставления.

    20.06.2014
  • У него нет проблем с отображением. Он мог бы сделать это с помощью нескольких заданий легко. Он хочет запустить запрос в базе данных, которая в данный момент работает в памяти. 20.06.2014
  • Хм, а разве это не только потому, что он не предварительно фильтруется? Фильтрация, которую можно применить к WebMessageDto, скорее всего будет подмножеством той, которая доступна для WebMessage. Итак, отфильтруйте, когда это WebMessage, а затем сопоставьте с WebMessageDto? 20.06.2014
  • Спасибо, но мне не нужно отображение. Я могу сделать это вручную. Мне нужно выполнить запрос к базе данных до отображения, а не после. 20.06.2014
  • @JesseJames - Вы пытаетесь вернуть подмножество столбцов? помогают ли расширения IQueryable? 20.06.2014
  • @AlexKey Я сделал сопоставление и использовал расширения. return DataContext.WebMessages.Project().To<WebMessageDto>(). Когда DataGrid запрашивает этот метод, он загружает all строк из базы данных, выполняет сопоставление, затем применяются условия запроса. Мне нужно применить условия запроса перед отображением. 23.06.2014
  • Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..