按选择顺序保存顺序(LINQ到XSD)
给定以下XML示例,我们可以将一个定义Root的模式想象为包含Type1和Type2之间的一系列未绑定选项。
<Root>
<Type1 />
<Type2 />
<Type2 />
<Type1 />
</Root>
我正在测试从XSD.exe工具迁移出来,尽管这种工具增加了类型安全性,但却有许多小小的烦恼。 在这种情况下,XSD工具只是在Root中创建一个System.Object类型的数组,并且必须确定其中存在哪些类型的对象(Type1或Type2)。 它不完全优雅,但至少你保持秩序。
问题是,当LINQ to XSD创建对象时,它将Root定义为具有两个独立的Type1和Type2列表。 这很好,因为它是类型安全的,但我现在似乎失去了元素的顺序。 我从codeplex上的源码构建了LINQ to XSD。
使用LINQ to XSD,我怎样才能保持这些元素的顺序?
如何在Choice上创建一个包装? 限制它像这样访问的类型:
class Choice
{
private object _value;
public ChoiceEnum CurrentType { get; private set; }
public Type1 Type1Value
{
get { return (Type1) _value; }
set { _value = value; CurrentType = ChoiceEnum.Type1; }
}
public Type2 Type2Value
{
get { return (Type2) _value; }
set { _value = value; CurrentType = ChoiceEnum.Type2; }
}
}
这是一个简化的版本,你将不得不添加更多的验证(如果_value
是正确的类型,什么是_value
的当前类型等)。
然后,你可以用LINQ过滤它:
var q1 = from v in root.Sequence
where v.CurrentType == ChoiceEnum.Type1
select v.Type1;
或者您可以在Root中创建方法来包装查询。
当有一个xsd:choice元素时,Linq2Xsd仅在序列上跳跃。
幸运的是,我能够删除我正在使用的Amazon XSD的xsd:选项(我只是没有使用MerchantOrderID),它允许将序列正确保存在xml的ToString()
中。
<xsd:choice> <--- removed line
<xsd:element ref="AmazonOrderID"/>
<xsd:element ref="MerchantOrderID"/> <--- removed line
</xsd:choice> <--- removed line
<xsd:element name="ActionType" minOccurs="0" maxOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Refund"/>
<xsd:enumeration value="Cancel"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
生成的代码然后正确地在保存顺序的构造函数中有这个
contentModel = new SequenceContentModelEntity(
new NamedContentModelEntity(XName.Get("AmazonOrderID", "")),
new NamedContentModelEntity(XName.Get("ActionType", "")),
new NamedContentModelEntity(XName.Get("CODCollectionMethod", "")),
new NamedContentModelEntity(XName.Get("AdjustedItem", "")));
您也可以通过自己创建子类来手动完成此操作,但我不确定这是如何与xsd:choice配合使用的。 这在这里描述,但我没有测试它。
链接地址: http://www.djcxy.com/p/883.html