在林克,什么是相反的.选择()

本文关键字:选择 林克 什么 | 更新日期: 2023-09-27 18:00:27

在Linq查询中,如果我想选择除特定属性外的所有属性,我该怎么办?

我不能使用Select()并指定除我不想要的属性之外的所有属性,因为我不知道其中的一些属性(我查询抽象类的列表)。

我不能只选择所有属性,因为在序列化X类型的对象时检测到会抛出循环引用。(我正在将对象序列化为Json)

有什么Filter()方法或一些扩展方法我可以使用吗?

谢谢。

在林克,什么是相反的.选择()

不,你不能那样做——根本没有这样的事情。请记住,由于投影的结果,您最终必须使用特定类型。。。如果你不知道要选择什么属性,你怎么能有这样的类型?

如果您正在查询某个抽象类的列表,是否有任何理由不想只保留对该抽象类实例的引用?将其划分为特定属性有什么好处?还是您真的试图避免以后看到这些属性,例如数据绑定?

如果JSON序列化是您试图解决的真正问题,请查看名为JSON和循环引用异常的帖子。一个建议是使用ScriptIgnoreAttribute类,该类"指定JavaScriptSerializer不会序列化公共属性或公共字段"。帖子中还有一些其他巧妙的方法值得考虑。

根据您谈论的属性数量,您最好的选择可能只是键入您想要的属性。正如Jon Skeet所指出的,LINQ中没有任何预先构建的功能可以实现您所描述的功能,因为这是一项非常不寻常的任务。

话虽如此,如果你要处理的属性太多,以至于写起来很痛苦——比如。。。

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

然后脑海中浮现出两个选项:

  • 使用脚本为您生成代码——可能是通过使用反射打印类的属性列表和C&将其Ping到您的代码中
  • 在活动代码中使用反射,使用PropertyInfo类并通过PropertyInfo.Name进行筛选

这两项我都做过(出于其他原因),所以我知道它们有效。然而,如果你能让它运行起来,我强烈建议你选择第一个选项。在实时代码中使用反射会更慢,可能更容易出错,并且当另一个开发人员出现时更难理解。我使用它的唯一原因是,与我一起工作的班级来自其他地方,而且经常发生变化。

如果您确实使用了第一个,则可能希望将代码保留在一个单独的辅助类中。没有人希望一大堆的房地产选择打乱了一个重要的方法。

好吧,你到底想实现什么?如果您想在序列化之前解决循环问题,为什么不遍历对象模型,并将所有backreferences设置为null呢?

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());  
  }  
}