【问题标题】:LINQ Statement WHERE QuestionLINQ 语句 WHERE 问题
【发布时间】:2011-07-14 17:23:59
【问题描述】:

我要返回一个列表。这是包含在我的 XML 文件中不能为空的 xml 节点的名称。

List<Setting> settingList = SettingsGateway.GetBySettingTypeList("VerifyField");

我有一个 LINQ 语句。我正在尝试返回所有具有空节点的事务。此处的列表返回不能为空的节点。有谁知道我在这里做错了什么?

以下代码应该将“事务”绑定到 DataGrid 并显示具有所需空节点的 Txn。

var transactionList =
from transactions in root.Elements(XName.Get("Transactions")).Elements().AsEnumerable()
where transactions.Elements().Any
(
    el => 
    //String.IsNullOrEmpty(el.Value) &&
    //elementsThatCannotBeEmpty.Contains(el.Name)
    settingList.Any(
        name => String.IsNullOrEmpty(el.Element(name.SettingValue).Value)
    )
)
select new
{
    CustomerName = transactions.Element(XName.Get("CustomerName")).Value,
    ConfirmationNumber = transactions.Element(XName.Get("ConfirmationNumber")).Value
 };

 GridView.DataSource = transactionList;
 GridView.DataBind();

XML 文件示例:

<OnlineBanking>
  <Transactions>
    <Txn>
      <UserName>John Smith</UserName>
      <CustomerStreet>123 Main</CustomerStreet>
      <CustomerStreet2></CustomerStreet2>
      <CustomerCity>New York</CustomerCity>
      <CustomerState>NY</CustomerState>
      <CustomerZip>12345</CustomerZip>
    </Txn>
  </Transactions>
</OnlineBanking>

【问题讨论】:

  • 不清楚为什么您不在内部 lambda 表达式中使用 nameSetting 长什么样子?
  • “不能为空”是什么意思?
  • 在XML中,节点不能为空。
  • 啊,好吧,有了那个编辑,它就更有意义了……
  • 设置有SettingIDSettingTypeSettingvalue。我返回所有设置类型为“VerifyField”的行,它们是CustomerStreetCustomerCityCustomerStateCustomerZip

标签: c# asp.net linq


【解决方案1】:

好的,第一个问题:如果元素丢失,你会得到一个 NullReferenceException。

我建议创建一个不能为空的元素的List&lt;string&gt;,以简化查询。那么:

var requiredElements = settingList.Select(x => x.SettingValue).ToList();

var transactionList = root
      .Elements("Transactions")
      .Elements("Txn")
      .Where(x => requiredElements
                    .Any(name => string.IsNullOrEmpty((string) x.Element(name)));

认为应该没问题,并且比您的原始代码稍微简单...但老实说,您的原始代码看起来应该可以正常工作。它实际上做了什么?您对实际结果与预期结果不是很清楚......

【讨论】:

  • 我用更多信息更新了我的代码。我添加了更多实际代码来向您展示我如何选择节点并将它们绑定到数据网格。我希望这可以帮助你,帮助我。
【解决方案2】:

类似这样的:

var transactionList =
     root
    .Elements(XName.Get("Transactions")) //Get <Transaction> elements
    .Elements() //Get <Txn> elements
    .Where(txn => txn.Elements().Any(e => e.Value == String.Empty))  //Filter <Txn> Elements if it have any element like this: <CustomerStreet2></CustomerStreet2>
    .Select(x => new {
        PropertyX = x.Element(XName.Get("UserName")),
        PropertyY = x.Element(XName.Get("CustomerStreet")),
                    ...
    });

适用于:

<OnlineBanking>
  <Transactions>
    <Txn> <!-- This one matches! -->
      <UserName>John Smith</UserName>
      <CustomerStreet>123 Main</CustomerStreet>
      <CustomerStreet2></CustomerStreet2> 
      <CustomerCity>New York</CustomerCity>
      <CustomerState>NY</CustomerState>
      <CustomerZip>12345</CustomerZip>
    </Txn>
    <Txn> <!-- This one doesn't match! -->
      <UserName>John Smith</UserName>
      <CustomerStreet>123 Main</CustomerStreet>
      <CustomerStreet2>ASDASD</CustomerStreet2>
      <CustomerCity>New York</CustomerCity>
      <CustomerState>NY</CustomerState>
      <CustomerZip>12345</CustomerZip>
    </Txn>
  </Transactions>
</OnlineBanking>

【讨论】:

  • 如何在其中添加“选择”,类似于我在上面的代码中添加的方式。我将 transactionList 绑定到 DataView 并有两列 ConfirmationNumberCustomerName
  • 您的代码正在返回 XML 文件中的所有 Txn,但它不应该返回。
  • 你确定吗?我用 2 个 样本试了一下,成功了。
  • 我在上面的@Jon 示例中得到了它。您的代码中没有 var requiredElements = settingList.Select(x =&gt; x.SettingValue).ToList();
  • 感谢您的帮助,@Tocco。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多