C#Linq在子查询中获得后代

时间:2017-02-28 03:16:47

标签: c# linq

过去几个小时我一直在桌面上试图解读这个问题。

我尝试使用Linq查询XML文件,xml具有以下格式:

<MRLGroups>
<MRLGroup>
    <MarketID>6084</MarketID>
    <MarketName>European Union</MarketName>
    <ActiveIngredientID>28307</ActiveIngredientID>
    <ActiveIngredientName>2,4-DB</ActiveIngredientName>
    <IndexCommodityID>59916</IndexCommodityID>
    <IndexCommodityName>Cucumber</IndexCommodityName>
    <ScientificName>Cucumis sativus</ScientificName>
    <MRLs>
        <MRL>
            <PublishedCommodityID>60625</PublishedCommodityID>
            <PublishedCommodityName>Cucumbers</PublishedCommodityName>
            <MRLTypeID>238</MRLTypeID>
            <MRLTypeName>General</MRLTypeName>
            <DeferredToMarketID>6084</DeferredToMarketID>
            <DeferredToMarketName>European Union</DeferredToMarketName>
            <UndefinedCommodityLinkInd>false</UndefinedCommodityLinkInd>
            <MRLValueInPPM>0.0100</MRLValueInPPM>
            <ResidueDefinition>2,4-DB</ResidueDefinition>
            <AdditionalRegulationNotes>Comments.</AdditionalRegulationNotes>
            <ExpiryDate xsi:nil="true" />
            <PrimaryInd>true</PrimaryInd>
            <ExemptInd>false</ExemptInd>
        </MRL>
        <MRL>
            <PublishedCommodityID>60626</PublishedCommodityID>
            <PublishedCommodityName>Gherkins</PublishedCommodityName>
            <MRLTypeID>238</MRLTypeID>
            <MRLTypeName>General</MRLTypeName>
            <DeferredToMarketID>6084</DeferredToMarketID>
            <DeferredToMarketName>European Union</DeferredToMarketName>
            <UndefinedCommodityLinkInd>false</UndefinedCommodityLinkInd>
            <MRLValueInPPM>0.0100</MRLValueInPPM>
            <ResidueDefinition>2,4-DB</ResidueDefinition>
            <AdditionalRegulationNotes>More Comments.</AdditionalRegulationNotes>
            <ExpiryDate xsi:nil="true" />
            <PrimaryInd>false</PrimaryInd>
            <ExemptInd>false</ExemptInd>
        </MRL>
    </MRLs>
</MRLGroup>

到目前为止,我已经为&#34; MRLGroup&#34;创建了课程。文件的一部分

 var queryMarket = from market in doc.Descendants("MRLGroup")
                          select new xMarketID
                          {
                              MarketID = Convert.ToString(market.Element("MarketID").Value),
                              MarketName = Convert.ToString(market.Element("MarketName").Value)
                          };
        List<xMarketID> markets = queryMarket.Distinct().ToList();

        var queryIngredient = from ingredient in doc.Descendants("MRLGroup")
                              select new xActiveIngredients
                              {
                                  ActiveIngredientID = Convert.ToString(ingredient.Element("ActiveIngredientID").Value),
                                  ActiveIngredientName = Convert.ToString(ingredient.Element("ActiveIngredientName").Value)
                              };
        List<xActiveIngredients> ingredientes = queryIngredient.Distinct().ToList();

        var queryCommodities = from commodity in doc.Descendants("MRLGroup")
                               select new xCommodities {
                                   IndexCommodityID = Convert.ToString(commodity.Element("IndexCommodityID").Value),
                                   IndexCommodityName = Convert.ToString(commodity.Element("IndexCommodityName").Value),
                                   ScientificName = Convert.ToString(commodity.Element("ScientificName").Value)
                               };
        List<xCommodities> commodities = queryCommodities.Distinct().ToList();

我得到&#34;目录&#34;我试图根据目录查询文档以实现某种类型的&#34;组&#34;,在这之后,我将把这些数据发送到数据库,这里的问题是xml文件大约每个600MB,我每天都会得到,所以我的方法是创建目录,然后将MRL发送到加入&#34;标题&#34;包含目录ID的表格,这里是我迄今为止所做的但是失败了:

 //markets
        foreach (xMarketID market in markets) {
            //ingredients
            foreach (xActiveIngredients ingredient in ingredientes) {
                //commodities
                foreach (xCommodities commodity in commodities) {
                    var mrls = from m in doc.Descendants("MRLGroup")
                               where Convert.ToString(m.Element("MarketID").Value) == market.MarketID
                               && Convert.ToString(m.Element("ActiveIngredientID").Value) == ingredient.ActiveIngredientID
                               && Convert.ToString(m.Element("IndexCommodityID").Value) == commodity.IndexCommodityID
                               select new
                               {
                                   ms = new List<xMRLIndividial>(from a in m.Element("MRLs").Descendants()
                                                                 select new xMRLIndividial{
                                                                     publishedCommodityID = string.IsNullOrEmpty(a.Element("PublishedCommodityID").Value) ? "" : a.Element("PublishedCommodityID").Value,
                                                                     publishedCommodityName = a.Element("PublishedCommodityName").Value,
                                                                     mrlTypeId = a.Element("MRLTypeID").Value,
                                                                     mrlTypeName = a.Element("MRLTypeName").Value,
                                                                     deferredToMarketId = a.Element("DeferredToMarketID").Value,
                                                                     deferredToMarketName = a.Element("DeferredToMarketName").Value,
                                                                     undefinedCommodityLinkId = a.Element("UndefinedCommodityLinkInd").Value,
                                                                     mrlValueInPPM = a.Element("MRLValueInPPM").Value,
                                                                     residueDefinition = a.Element("ResidueDefinition").Value,
                                                                     additionalRegulationNotes = a.Element("AdditionalRegulationNotes").Value,
                                                                     expiryDate = a.Element("ExpiryDate").Value,
                                                                     primaryInd = a.Element("PrimaryInd").Value,
                                                                     exemptInd = a.Element("ExemptInd").Value
                                                                 })

                               };
                    foreach (var item in mrls)
                    {
                        Console.WriteLine(item.ToString());
                    }
                }
            }
        }

如果你注意到我试图获得MRLs的后代,但我收到了这个错误:

enter image description here

我可以通过&#34; a&#34;变量是MRL的第一个节点 - &gt; MRL不是全部,发生了什么?

如果你们可以借给我一只手就超级棒!

提前致谢。

1 个答案:

答案 0 :(得分:1)

用这条线......

from a in m.Element("MRLs").Descendants()

...将遍历所有子元素,包括孩子的子元素。因此您的错误,因为您的<PublishedCommodityID>元素没有子元素。

除非您想要专门返回所有级别的所有子元素,否则请始终使用ElementElements轴而不是DescendantDescendants

from a in m.Element("MRLs").Elements()

这应该可以解决你的问题。

但是,使用嵌套的foreach循环和ID的多个测试也很难读取您的查询。您可以结合使用LINQ和XPath来简化它:

var mrls =
    from market in markets
    from ingredient in ingredientes
    from commodity in commodities
    let xpath = $"/MRLGroups/MRLGroup[{market.MarketId}]" +
        $"[ActiveIngredientID={ingredient.ActiveIngredientId}]" +
        $"[IndexCommodityID={commodity.IndexCommodityID}]/MRLs/MRL"
    select new {
        ms =
            (from a in doc.XPathSelectElements(xpath)
            select new xMRLIndividial {
                publishedCommodityID = string.IsNullOrEmpty(a.Element("PublishedCommodityID").Value) ? "" : a.Element("PublishedCommodityID").Value,
                publishedCommodityName = a.Element("PublishedCommodityName").Value,
                mrlTypeId = a.Element("MRLTypeID").Value,
                mrlTypeName = a.Element("MRLTypeName").Value,
                deferredToMarketId = a.Element("DeferredToMarketID").Value,
                deferredToMarketName = a.Element("DeferredToMarketName").Value,
                undefinedCommodityLinkId = a.Element("UndefinedCommodityLinkInd").Value,
                mrlValueInPPM = a.Element("MRLValueInPPM").Value,
                residueDefinition = a.Element("ResidueDefinition").Value,
                additionalRegulationNotes = a.Element("AdditionalRegulationNotes").Value,
                expiryDate = a.Element("ExpiryDate").Value,
                primaryInd = a.Element("PrimaryInd").Value,
                exemptInd = a.Element("ExemptInd").Value
            }).ToList()
    };