按选择顺序保存顺序(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

上一篇: Preserving Order In Sequence of Choices (LINQ To XSD)

下一篇: Unique Messages per Queue in AMQP?