【问题标题】:Search using a Predicate on a Domain Class使用域类上的谓词进行搜索
【发布时间】:2016-07-01 18:20:19
【问题描述】:

在 LINQ to Objects 中,可以使用谓词轻松过滤集合的子集,例如如果我的域类是Person,则集合是persons,谓词Func<Person, bool> filter,则类似于persons.Where(filter).ToArray()

与序列化为XElement 的人员集合具有相同的功能:

XElement[] xFiltered = xPersons.Elements("Person")
                               .Where(xFilter)
                               .ToArray();

其中xPersons 是包含人员元素(每个名为“Person”)的根元素,Func<XElement, bool> xFilter 是在XElement 上定义的谓词作为参数类型。

我想知道是否存在直接的可能性在 LINQ for XML 中创建一个Where 语句,该语句将Func<Person, bool> 类型的谓词作为参数,而不是Func<XElement, bool>?为此,需要实现一个转换器将Func<Person, bool> 转换为Func<XElement, bool>,但这似乎是一种违反直觉且容易出错的操作。能否设想出这种真正的转换器(例如,基于检查)?或者它只是存在?

【问题讨论】:

  • 目前我们不知道您将如何从XElement 构建Person...一旦您掌握了,剩下的就很容易了。

标签: c# xml linq linq-to-xml


【解决方案1】:

您可以在底层 XElement(s) 和 XAttribute(s) 上构建谓词,例如

xPersons.Elements("Person")
        .Where(e => (string)e.Attribute("Name") == "Alex")

要使用Person类,你需要先反序列化它:

xPersons.Elements("Person")
        .Select(e => CreatePerson(e))
        .Where(p => p.Name == "Alex")

private static Person CreatePerson(XElement element)
{
    // your (de)serialization logic goes here
}

或者你可以在你的类中写一个显式的转换操作符:

xPersons.Elements("Person")
        .Where(e => ((Person)e).Name) == "Alex")

public static explicit operator Person(XElement element)
{
    // your (de)serialization logic goes into your Person class
}

【讨论】:

  • 是的,Person 类有一个 FromXElement(XElement x) 函数,它等同于您的解决方案。但是,如果我反序列化整个集合然后用 Func. 过滤它,这将是相同的(恕我直言)
  • @AlexKonnen:是的,您可以序列化每个元素或整个集合。这是我看到的使用类 Person 而不是 XML 内容的唯一方法。
猜你喜欢
  • 2013-12-26
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2018-01-19
  • 1970-01-01
相关资源
最近更新 更多