【问题标题】:Project attribute values项目属性值
【发布时间】:2015-10-13 18:42:41
【问题描述】:

不确定这是否可能。我有一部分“MarketInventory”节点:

<MARKET_INVENTORY _Type="TotalSales" _MonthRangeType="Prior7To12Months" _Count="18"/>
<MARKET_INVENTORY _Type="TotalSales" _MonthRangeType="Prior4To6Months" _Count="6"/>
<MARKET_INVENTORY _Type="TotalSales" _MonthRangeType="Last3Months" _Count="11"/>
<MARKET_INVENTORY _Type="TotalSales" _TrendType="Stable"/>

在 _Type="TotalSales" 节点上过滤。

我想知道是否可以将 _Count 值属性投影到此类中:

public class MarketInventoryListing
{
    public string Prior7To12Months { get; set; }
    public string Prior4To6Months { get; set; }
    public string LastThreeMonths { get; set; }
}

据我所知:

var marketInventoryTotalListings = from totalListings in xe.Descendants("MARKET_INVENTORY")
where (string) totalListings.Attribute("_Type") == "TotalSales"
select new MarketInventoryListing()
{
    Prior7To12Months = 
    (
        from thing in totalListings.Descendants()
        where (string)totalListings.Attribute("_MonthRangeType") == "Prior7To12Months"
        select thing.Attribute("_Count").Value
    )
};

【问题讨论】:

  • Prior7To12Monthsstring 类型,而 linq 查询返回 IEnumerable&lt;string&gt;

标签: c# linq linq-to-xml


【解决方案1】:

它不起作用有两个原因:

  1. Select 在您需要单个字符串的地方返回 IEnumerable
  2. 所有 MARKET_INVENTORY 元素都在同一级别,因此“来自 totalListings.Descendants() 中的事物”不会返回任何内容。在这一点上,所有这些元素都是同级元素。

我更改了您的代码以解决这些问题,它的工作原理如下:

var marketInventoryTotalListings = (from totalListings in xe.Descendants("MARKET_INVENTORY")
                                   where (string)totalListings.Attribute("_Type") == "TotalSales"
                                   select new MarketInventoryListing()
                                   {
                                      Prior7To12Months =
                                      (
                                           from thing in totalListings.Parent.Descendants()
                                           where (string)totalListings.Attribute("_MonthRangeType") == "Prior7To12Months"
                                           select thing.Attribute("_Count").Value
                                      ).FirstOrDefault(),
                                   }).FirstOrDefault();

【讨论】:

    【解决方案2】:

    如果您确定每个节点只有一个,那么您可以像这样使用FirstOrDefault:-

    var marketInventoryTotalListings = from totalListings in xe.Descendants("MARKET_INVENTORY")
      where (string)totalListings.Attribute("_Type") == "TotalSales"
      let prior712 = xe.Descendants("MARKET_INVENTORY")
            .FirstOrDefault(x => (string)x.Attribute("_MonthRangeType") == "Prior7To12Months")
      let prior46 = xe.Descendants("MARKET_INVENTORY")
            .FirstOrDefault(x => (string)x.Attribute("_MonthRangeType") == "Prior4To6Months")
      let last3 = xe.Descendants("MARKET_INVENTORY")
            .FirstOrDefault(x => (string)x.Attribute("_MonthRangeType") == "Last3Months")
      select new MarketInventoryListing
         {
             Prior7To12Months = prior712 != null ? (string)prior712.Attribute("_Count") : "",
             Prior4To6Months = prior712 != null ? (string)prior46.Attribute("_Count") : "",
             LastThreeMonths = last3 != null ? (string)last3.Attribute("_Count") : "",
         };
    

    否则,如果它们是多个,那么您应该将 IEnumerable&lt;string&gt; 作为 MarketInventoryListing 属性中的数据类型,而不是 string

    【讨论】:

    • Rahul - 我在 'let' 语句中将 'xdoc' 更改为 'xe' 并在末尾添加了 'FirstOrDefault() 并且它起作用了。感谢您的回复!
    • @FoolongCv- 是的,这是一个错字;)已更正。
    猜你喜欢
    • 1970-01-01
    • 2018-09-15
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 2017-10-01
    • 2013-10-15
    相关资源
    最近更新 更多