我有一个深度为4的XML结构:
<?xml version="1.0" encoding="utf-8"?>
<EmailRuleList xmlns:xsd="EmailRules.xsd">
<TargetPST name="Tech Communities">
<Parse emailAsList="true" useJustDomain="false" fromAddress="false" toAddress="true">
<EmailRule address="@aspadvice.com" folder="Lists, ASP" saveAttachments="false" />
<EmailRule address="@sqladvice.com" folder="Lists, SQL" saveAttachments="false" />
<EmailRule address="@xmladvice.com" folder="Lists, XML" saveAttachments="false" />
</Parse>
<Parse emailAsList="false" useJustDomain="false" fromAddress="false" toAddress="true">
<EmailRule address="northcoloradoarchitects@googlegroups.com" folder="Special Interest Groups|Northern Colorado Architects Group" saveAttachments="false" />
<EmailRule address="spambayes@python.org" folder="Support|SpamBayes" saveAttachments="false" />
</Parse>
<Parse emailAsList="false" useJustDomain="false" fromAddress="true" toAddress="false">
<EmailRule address="support@godaddy.com" folder="Support|GoDaddy" saveAttachments="false" />
<EmailRule address="renew@no-ip.com" folder="Support|No-IP.com" saveAttachments="false" />
<EmailRule address="discuss@orchardproject.net" folder="Discussions|Orchard Project" saveAttachments="false" />
</Parse>
<Parse emailAsList="false" useJustDomain="true" fromAddress="true" toAddress="false">
<EmailRule address="@agilejournal.com" folder="Newsletters|Agile Journal" saveAttachments="false"/>
<EmailRule address="@axosoft.ccsend.com" folder="Newsletters|Axosoft Newsletter" saveAttachments="false"/>
<EmailRule address="@axosoft.com" folder="Newsletters|Axosoft Newsletter" saveAttachments="false"/>
<EmailRule address="@cmcrossroads.com" folder="Newsletters|CM Crossroads" saveAttachments="false" />
<EmailRule address="@urbancode.com" folder="Newsletters|Urbancode" saveAttachments="false" />
<EmailRule address="@urbancode.ccsend.com" folder="Newsletters|Urbancode" saveAttachments="false" />
<EmailRule address="@Infragistics.com" folder="Newsletters|Infragistics" saveAttachments="false" />
<EmailRule address="@zdnet.online.com" folder="Newsletters|ZDNet Tech Update Today" saveAttachments="false" />
<EmailRule address="@sqlservercentral.com" folder="Newsletters|SQLServerCentral.com" saveAttachments="false" />
<EmailRule address="@simple-talk.com" folder="Newsletters|Simple-Talk Newsletter" saveAttachments="false" />
</Parse>
</TargetPST>
<TargetPST name="[Sharpen the Saw]">
<Parse emailAsList="false" useJustDomain="false" fromAddress="false" toAddress="true">
<EmailRule address="rmiug-jobs@yahoogroups.com" folder="Head Geek|Job Alerts" saveAttachments="false" />
<EmailRule address="inkedinusmc@yahoogroups.com" folder="Social|LinkedIn USMC" saveAttachments="false"/>
</Parse>
<Parse emailAsList="false" useJustDomain="false" fromAddress="true" toAddress="false">
<EmailRule address="JobAlerts@CyberCoders.com" folder="Head Geek|Job Alerts" saveAttachments="false" />
<EmailRule address="jobs@dice.com" folder="Head Geek|Job Alerts" saveAttachments="false" />
<EmailRule address="news@cruisecritic.com" folder="Social|Cruise Critic" saveAttachments="false"/>
</Parse>
<Parse emailAsList="false" useJustDomain="true" fromAddress="true" toAddress="false">
<EmailRule address="@moody.edu" folder="Social|5 Love Languages" saveAttachments="false" />
<EmailRule address="@postmaster.twitter.com" folder="Social|Twitter" saveAttachments="false"/>
<EmailRule address="@diabetes.org" folder="Physical|American Diabetes Association" saveAttachments="false"/>
<EmailRule address="@membership.webshots.com" folder="Social|Webshots" saveAttachments="false"/>
</Parse>
</TargetPST>
</EmailRuleList>
现在,我有一个FromAddress和一个ToAddress,它是从传入的电子邮件中解析的。我想针对从此XML反序列化的类集执行LINQ查询。例如: ToAddress = asp@aspadvice.com FromAddress = keithb@sol3.net
查询:
我很难搞清楚这个LINQ查询。当然,我可以循环遍历XML中的所有位(包括反序列化到对象中):
XmlSerializer s = new XmlSerializer(typeof(EmailRuleList));
TextReader r = new StreamReader(path);
_emailRuleList = (EmailRuleList)s.Deserialize(r);
TargetPST[] PSTList = _emailRuleList.Items;
foreach (TargetPST targetPST in PSTList)
{
olRoot = GetRootFolder(targetPST.name);
if (olRoot != null)
{
Parse[] ParseList = targetPST.Items;
foreach (Parse parseRules in ParseList)
{
EmailRule[] EmailRuleList = parseRules.Items;
foreach (EmailRule targetFolders in EmailRuleList)
{
}
}
}
}
但是,这意味着要为每个地址遍历所有这些循环。查询对象对我来说更有意义。任何提示赞赏!
答案 0 :(得分:1)
这里有你的代码:
XmlSerializer s = new XmlSerializer(typeof(EmailRuleList));
TextReader r = new StreamReader(path);
_emailRuleList = (EmailRuleList)s.Deserialize(r);
TargetPST[] PSTList = _emailRuleList.Items;
foreach (TargetPST targetPST in PSTList)
{
olRoot = GetRootFolder(targetPST.name);
if (olRoot != null)
{
Parse[] ParseList = targetPST.Items;
foreach (Parse parseRules in ParseList)
{
EmailRule[] EmailRuleList = parseRules.Items;
foreach (EmailRule targetFolders in EmailRuleList)
{
}
}
}
}
在LINQ中实际上只是以下内容:
var query = from targetPST in _emailRuleList.Items
let olRoot = GetRootFolder(targetPST.name)
where olRoot != null
from parseList in targetPST.Items
from emailRule in parseList.Items
select [whatever you want to select];
从这里开始,只需包含相应的where子句。在每个“级别”,您都可以访问先前在from子句中指定的对象,因此如果您想要执行其中一个查询(第一个),则可能是这样的:
where emailRule.address == ToAddress &&
parseList.toAddress == true &&
parseList.useJustDomain == false
select new {
EmailRule = emailRule,
Parse = parseList,
TargetPST = targetPST
}
要在方法中这样做,我认为你的弊大于利(特别是在可读性方面),但在这里。关于为什么这么复杂的重要事项是嵌套的FROM子句转换为SelectMany,并且因为最终你需要EmailRule及其关联的父对象,你必须在一组嵌套的lambdas中进行所有选择为了引用父对象(因为子对象本身没有反向引用)。
_emailRuleList
.Where( targetPst => GetRootFolder( targetPst.Name ) != null )
.SelectMany( targetPst => {
return targetPst.Items.SelectMany( parse => {
return parse.Items.Select( rule => {
return new {
TargetPST = targetPst,
Parse = parse,
EmailRule = rule
};
} );
} );
} )
.Where( x => x.EmailRule.address == ToAddress &&
x.Parse.toAddress == true &&
x.Parse.useJustDomain == false );