我非常擅长使用LINQ。我有以下XML:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<RetentionValue code="NR" fullName="Normal Retention">Used for normal retention periods commonly expressed as only numbers (i.e. "25" for 25 years).</RetentionValue>
<RetentionValue code="SR" fullName="Short Retention">Used for short retention periods expressed in terms of months (i.e. "6 months").</RetentionValue>
<RetentionValue code="AR" fullName="Annual Review">Review annually and retain what is needed, dispose of what is not needed.</RetentionValue>
<RetentionValue code="PE" fullName="Permanent">Document is to be retained permanently.</RetentionValue>
<RetentionValue code="EX" fullName="Expiration">Disposal date is calculated from expiration of a contract, loan, or other such instrument.</RetentionValue>
<RetentionValue code="LI" fullName="Lifetime">Disposal date is calculated from the end-of-life date for a piece of equipment or other asset (e.g. software application).</RetentionValue>
<RetentionValue code="TE" fullName="Employee Termination">Disposal date is calculated from the date of termination or retirement of an employee.</RetentionValue>
<RetentionValue code="FR" fullName="Final Resolution">Disposal date is calculated from the date of final resolution for an issue.</RetentionValue>
</root>
在我的代码中,我创建了一个具有属性RetentionEvent
的对象,其值为上面两个字母代码之一。我想找到具有匹配属性的Element,然后将fullName
返回到一个文本字段,将值(wordy description)返回到另一个文本字段。到目前为止,我有以下内容:
// Construct a RecordDisposal object by passing it a valid retention code.
// An exception will be thrown if the code is not valid.
_rd = new RecordDisposal(RetentionCode.Text);
// Load up XML file with description of codes.
XDocument rangeValues = XDocument.Load("DisposalRangeValues.xml");
XElement codeValue = rangeValues.Root.Elements().Single(x => (string)x.Attribute("code") == _rd.DisposalList[0].RetentionEvent);
CodeName.Text = codeValue.Attribute("fullName").Value.ToString();
CodeDescription.Text = codeValue.Value.ToString();
查询是this代码的直接模式(我认为),但是我遇到了一些我不理解的错误:“查询正文必须以select子句结束或者一个组子句“(我认为这是ToList()
的用途),而”select子句中表达式的类型是不正确的。在调用'Select'时类型推断失败。“不幸的是,我不太了解Linq对此进行故障排除,并且”对此错误的帮助“没有提供任何帮助。
我做错了什么?另外,我怀疑ToList()
函数会在ToString()
函数中返回一些不能很好地呈现的东西,但我还在等待弄清楚其他东西。如果有人有任何建议,请提供。
编辑:根据以下建议修改代码以使用Single。发现rangeValues
正在将所有<root>
作为单个节点加载。
EDIT2:想出来了。修改后的代码代替使用rangeValues.Root.Elements()
。更新了上面的代码以反映。
答案 0 :(得分:1)
您的.ToList()
调用是正确的,但LINQ查询的语法不正确。
试试这个:
List<XElement> fullnames = (from fullName in rangeValues.Elements()
where fullName.Attribute("code") == _rd.DisposalList[0].RetentionEvent
select fullName).ToList();
答案 1 :(得分:1)
稍微重新格式化,您的代码如下所示:
XElement codeValue =
from fullName
in rangeValues.Elements()
.Where(x => (string)x.Attribute("code") == _rd.DisposalList[0].RetentionEvent)
.ToList();
// select ???
因此ToList()
已应用于您的查询的in
部分,但您错过了select
声明。
实际上,由于您希望返回单个XElement
,您可能需要这样的内容,它会选择集合中唯一与Single()
中指定的子句相匹配的元素:< / p>
XElement codeValue =
(from fullName in rangeValues.Elements()
where (string)fullName.Attribute("code") == _rd.DisposalList[0].RetentionEvent
select fullName).Single();
备用语法(以上是查询语法,以下称为方法语法):
XElement codeValue =
rangeValues.Elements().Single(x => (string)x.Attribute("code") == _rd.DisposalList[0].RetentionEvent);
如果可能不匹配,或者可能不止一个,那么您也想研究SingleOrDefault()
,First()
和FirstOrDefault()
。