none
Исключение NotSupportedException при выполнении LINQ to Object к классу сущностей RRS feed

  • Вопрос

  • Здравствуйте.

    Выполняю LINQ to Object к классу сущностей, который перед этим был успешно заполнен данными из БД с помощью LINQ to SQL. Ниже привожу исходный текст метода, содержащего LINQ to Object.

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
      if (this.DialogResult == true)
      {
        using (SubjectReferenceDataContext context = new SubjectReferenceDataContext())
        {
          IQueryable<Subjects_contents> SubjectsReference = context.Subjects_contents;
          var selectedSubjects = from Subjects in SubjectsReference
                                 where Subjects.IsSelected == true
                                 select new
                                 {
                                   SubjectId = Subjects.Id,
                                   SubjectName = Subjects.Name,
                                 };
          foreach (var fut in selectedSubjects)
          {
            this.SubjectID = (Int32)fut.FuturesId;
            this.SubjectName = fut.FuturesName;
          }
        }
      }
    }

    Поле IsSelected класса сущностей Subjects_contents не базовое. И при выполнении цикла foreach возникает исключение NotSupportedException следующего содержания: Член "MyProject.Subjects_contents.IsSelected" не содержит поддерживаемого преобразования в SQL. Ниже привожу определение этого поля и свойства

    partial class SubjectContents
        {
            #region Fields
    
            /// <summary>
            /// Состояние субъекта:
            /// "Выбран" - true, "Не выбран" - false.
            /// </summary>
            private bool isSelected;
    
            #endregion
    
            #region Properties
    
            /// <summary>
            /// Возвращает или задаёт состояние субъекта:
            /// "Выбран" - true, "Не выбран" - false.
            /// </summary>
            public bool IsSelected
            {
                get { return isSelected; }
                set { isSelected = value; }
            }
    
            #endregion
        }

    Почему это происходит? Ведь LINQ to Object образно говоря должен чихать на БД. Он запрашивает данные из класса сущностей, а уж откуда они там появились - не его дело. Почему же тогда возникает исключение NotSupportedException? Без поля IsSelected я не могу обойтись. Это поле выбора, оно привязано к колонке WPF DataGrid типа radiobutton. Помогите, пожалуйста. Подскажите, что можно сделать что бы работало нормально?

    На всякий случай ниже привожу перечень пространств имён, используемых в классе диалога выбора:

    using System;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;

    С уважением  Евгений.

Ответы

Все ответы

  • Замените:

    IQueryable<Subjects_contents> SubjectsReference = ...

    на:

    IEnumerable<Subjects_contents> SubjectsReference = ...

    Отвечающий
  • Спасибо, Алексей. Исключение больше не появляется.
    • Изменено TownSparrow 4 мая 2012 г. 20:37
    • Помечено в качестве ответа TownSparrow 4 мая 2012 г. 20:37
    • Снята пометка об ответе Abolmasov Dmitry 5 мая 2012 г. 5:55
  • Ну и замечательно. Будут еще проблемы, обращайтесь.

    P.s. Помечайте в качестве ответа не то сообщение, которым закрываете ветку, а то сообщение, которое помогло вам решить проблему, чтобы другим пользоватлям столкнувшимся с такой проблемой было проще искать ответ.

    Отвечающий
  • "который перед этим был успешно заполнен данными из БД с помощью LINQ to SQL" - вот тут Вы ошибаетесь, так как LINQ использует отложенную загрузку, был сформирован запрос который будет выполнен в самый последний момент, а это в вашем случае цикл foreach.

    "Почему это происходит?" - потому что ORM(в вашем случае LINQ to SQl) не в состоянии транслировать дерево выражений в SQL.

    "Он запрашивает данные из класса сущностей, а уж откуда они там появились - не его дело."  - как раз дело это его. Важно то как их запрашиваете и откуда. Применяя последовательность типа IQueryable<T> Вы "заставляете LINQ думать" что весь запрос надо транслировать в SQL, так как в этом случае применяется не сам делегат, а его представление в виде дерева выражений. А когда заменили на IEnumerable<T> то уже Ваш второй запрос

    var selectedSubjects = from Subjects in SubjectsReference
                                 where Subjects.IsSelected == true
                                 select new
                                 {
                                   SubjectId = Subjects.Id,
                                   SubjectName = Subjects.Name,
                                 }

    ORM не пытается транслировать в SQL, так как тут уже происходит работа с самими делегатами, а не их представлениями. Тут уже ваше утверждение "а уж откуда они там появились - не его дело" - становится верным.


    Модератор