В Linq, что противоположно .Select()?

В запросе Linq, если я хочу выбрать все свойства, кроме определенного свойства, что бы я сделал?

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

Я также не могу просто выбрать все свойства, потому что это могло бы вызвать циклическую ссылку, обнаруженную при сериализации объекта типа X. (Я сериализую объект для Json)

Есть ли какой-либо метод Filter() или какой-либо метод расширения, который я могу использовать?

Спасибо.

Ответы

Ответ 1

Нет, вы не можете этого сделать - ничего подобного. Имейте в виду, что в результате проекции вы должны получить определенный тип... если вы не знаете, какие свойства вы собираетесь выбрать, как у вас такой тип?

Если вы запрашиваете список абстрактного класса, есть ли причина, по которой вы не хотите просто ссылаться на экземпляр этого абстрактного класса? Какая польза в том, чтобы отделить его от конкретных свойств? Или вы действительно пытаетесь избежать просмотра этих свойств позже, например. для привязки данных?

Ответ 2

Если сериализация JSON - это настоящая проблема, которую вы пытаетесь исправить, тогда проверьте сообщение, которое называется JSON и Circular Reference Exception. Одна из рекомендаций заключается в использовании ScriptIgnoreAttribute Class, который "Указывает, что JavaScriptSerializer не будет сериализовать публичное свойство или публичное поле". Есть также некоторые другие умные способы обойти это в заслуживающем внимания почте.

Ответ 3

Ну, что именно вы хотите достичь? Если вы хотите решить круговые проблемы перед сериализацией, почему бы не пересечь объектную модель, а затем установить все обратные ссылки на нуль?

public class MyClass{  
  public List<MyClass> Children {get;set;}  
  public MyClass Parent {get;set;}  

  public void ClearParents(){  
    this.Parent = null;  
    this.Children.ForEach(e => e.ClearParents());  
  }  
}

Ответ 4

В зависимости от количества свойств, о которых вы говорите, лучшим выбором может быть только то, что вы хотите. Как отмечает Джон Скит, в LINQ ничего не было встроено в LINQ, что делает то, что вы описываете, потому что это очень необычная задача.

Если говорить о том, что вы имеете дело с таким количеством свойств, что огромная боль для записи - например, что-то вроде...

return query.Select(q => new
                   {
                       Prop1 = q.Prop1,
                       Prop2 = q.Prop2,
                       //...
                       Prop3000 = q.Prop3000
                   });

... тогда есть два варианта, которые spring:

  • Используйте script для генерации кода для вас - возможно, используя отражение, чтобы распечатать список свойств класса и C & Ping его в ваш код.
  • Используйте отражение в вашем живом коде, используя PropertyInfo class и фильтрацию PropertyInfo.Name.

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

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