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

LINQ: без перевода в SQL

Можете ли вы объяснить, почему пример №1 не работает с «Без перевода в SQL», а пример №2 работает нормально?

Все в репозитории:

Пример 1:

public DomainPerson GetBestPerson()
{       
       var person= GetPeople().Where(p=>p.Quality=="Best").SingleOrDefault();
       return person;
}

public IQueryable<DomainPerson> GetPeople()
{
       var people= from p in Data.Persons
                   select MapToDomain(p);

       return people;
}

private DomainPerson MapToDomain(Data.Person dataPerson)
{   
       DomainPerson domainPerson= new DomainPerson{
                                  Id=dataPerson.Id,
                                  Name=dataPerson.Name,
                                  Quality=dataPerson.Quality,
                                  };
       return domainPerson;
}  

EX # 2

 public DomainPerson GetBestPerson()
{       
       var person= GetPeople().Where(p=>p.Quality=="Best").SingleOrDefault();
       return person;
}

public IQueryable<DomainPerson> GetPeople()
{
       var people= from p in Data.Persons
                   select new DomainPerson{
                   Id=dataPerson.Id,
                   Name=dataPerson.Name,
                   Quality=dataPerson.Quality,
                   };


       return people;
}
04.06.2009

Ответы:


1

Как уже упоминалось, это связано с кодом, с которым работает LINQ To SQL.

Вы должны смотреть на это примерно так. В вашем 1-м примере - если мы посмотрим на выражения (т.е. дерево выражений), которые будет генерировать GetPeople, - человеческими словами он генерирует дерево, которое указывает, что мы выбираем из нашей таблицы, а затем применяем функцию MapToDomain к каждой строке в этой таблице который возвращает объект типа DomainPerson.

Во втором примере на этот раз мы не только знаем, что возвращаемый тип - это DomainPerson, но мы также можем видеть, какие поля сопоставляются каким свойствам (и, что еще более важно, как). Это означает, что когда вы позже запустите свой Where и ссылку p.Quality, Linq To SQL может отследить это до таблицы SQL и знает, что DomainPerson.Quality отображается в столбец Quality в таблице Persons.

Поначалу может показаться немного странным, почему 1-й пример не работает, но предположим, что ваша модель MapToDomain выглядела так:

public void DomainPerson MapToDomain(Data.Person person){
    return new DomainPerson {
        Quality = person.Quality + " Quality";
        //mode code here
    };
}

Каким образом LINQ To SQL должен знать об этом «специальном» сопоставлении? - Ответ простой - не может.

Проще говоря, когда вы делаете что-либо в своем операторе select и хотите спроецировать свой результат, фактическое проецирование должно происходить как «встроенный» код (я не уверен в точном термине для этого), если вы хотите после этого больше выполнять запросы (т. е. упорядочивание, фильтрация и т. д.) - иначе у механизма запросов не будет возможности узнать, как работает ваше отображение.

04.06.2009

2

Причина в том, что LINQ to SQL работает путем преобразования деревьев выражений (Expression<Func<T>>) в SQL и выполнения его на сервере. Метод, на который вы ссылаетесь в №1, скомпилирован до IL. LINQ to SQL не может получить представление дерева выражения из своего тела.

Второй пример на самом деле не компилируется до IL. Он хранится в данных, которые могут быть прочитаны и переведены во время выполнения. В моем ответе на этот вопрос это подробно объясняется.

04.06.2009
  • Я действительно считаю, что настоящее имя типа - Expression ‹T› (а не ExpressionTree ‹T›) - по крайней мере, я никогда не слышал о ExpressionTree ‹T› 05.06.2009

  • 3

    В первом дереве выражения, созданном GetPeople (), содержится MapToDomain, который нельзя преобразовать в выражение SQL.

    Рассмотрите возможность изменения MapToDomain, чтобы он возвращал IQueryable ‹> (*, и исправьте оставшиеся вызовы MapToDomain (), чтобы они вызывали SingleOrDefault (). Проще сделать, чем объяснять, я не скомпилировал это, поскольку у меня нет доступных базовых объектов:

        public DomainPerson GetBestPerson()
        {       
               var person= GetPeople().Where(p=>p.Quality=="Best").SingleOrDefault();
               return person;
        }
    
        public IQueryable<DomainPerson> GetPeople()
        {
               return MapToDomain(Data.Persons);
        }
    
        IQueryable<DomainPerson> MapToDomain(IQueryable<Person> persons)
        {
            return persons.select(dataPerson => new DomainPerson{
                                          Id=dataPerson.Id,
                                          Name=dataPerson.Name,
                                          Quality=dataPerson.Quality,
                                          };
        }
    
    04.06.2009
  • Это в корне неверно. это сделало бы результирующий запрос IQueryable ‹IQueryable ‹DomainPerson››, что вообще не имеет смысла. 05.06.2009
  • Да, я пропустил некоторые шаги в своем объяснении, добавил код, чтобы прояснить 05.06.2009

  • 4

    Это нелогично, что конструктор DomainPerson можно транслировать, а метод MapToDomain - нет.

    Возможно, в этой истории есть нечто большее, чем показанный код. Здесь есть синтаксическая ошибка во втором примере:

    выберите новый DomainPerson {

    Это действительно анонимный тип в реальном коде?

    04.06.2009
    Новые материалы

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

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

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

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

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

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

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