简体   繁体   English

按顺序保留顺序(LINQ To XSD)

[英]Preserving Order In Sequence of Choices (LINQ To XSD)

Given the following XML example we could imagine a schema defining Root as containing a sequence of unbound number of choices between Type1 and Type2. 给定以下XML示例,我们可以想象一个模式将Root定义为包含Type1和Type2之间的未绑定数量的选择序列。

<Root>
    <Type1 />
    <Type2 />
    <Type2 />
    <Type1 />
</Root>

I am testing out migrating from the XSD.exe tool which although adds type-safety has a lot of little annoyances. 我正在测试从XSD.exe工具迁移,虽然添加类型安全有很多小烦恼。 The XSD tool in this case just creates within Root an array of type System.Object and you have to figure out what type of objects (Type1 or Type2) are in there. 在这种情况下,XSD工具只是在Root中创建一个System.Object类型的数组,你必须弄清楚那里有什么类型的对象(Type1或Type2)。 Its not completely elegant, but at least you preserve order. 它并不完全优雅,但至少你保留了秩序。

The problem is when LINQ to XSD creates the objects, it defines Root as having two independent lists of Type1 and Type2. 问题是当LINQ to XSD创建对象时,它将Root定义为具有两个独立的Type1和Type2列表。 This is great in that it is type-safe, but I now appear to lose the order of the elements. 这很棒,因为它是类型安全的,但我现在似乎失去了元素的顺序。 I built LINQ to XSD from the source on codeplex. 我在codeplex上从源代码构建了LINQ to XSD。

Using LINQ to XSD, how can I preserve the order of these elements? 使用LINQ to XSD,我如何保留这些元素的顺序?

How about creating a wrapper around Choice? 如何在Choice周围创建一个包装器? Limiting the types that it accesses like this: 限制它访问的类型,如下所示:

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; }
    }
}

This is a simplified version, and you will have to add more validation (if _value is of correct type, what is the current type of _value , etc). 这是一个简化版本,您必须添加更多验证(如果_value的类型正确, _value的当前类型是_value ,等等)。

Then, you can filter it with LINQ: 然后,您可以使用LINQ过滤它:

var q1 = from v in root.Sequence
         where v.CurrentType == ChoiceEnum.Type1
         select v.Type1;

Or you can create methods in Root that will wrap the queries. 或者,您可以在Root中创建将包装查询的方法。

Linq2Xsd only trips up on sequences when there's an xsd:choice element. 当有一个xsd:choice元素时,Linq2Xsd只会跳过序列。

Fortunately I was able to remove the xsd:choice for the Amazon XSD I am using (I just wasn't using MerchantOrderID), which allowed the sequence to properly be preserved in the ToString() for the xml. 幸运的是,我能够删除我正在使用的Amazon XSD的xsd:choice(我只是没有使用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> 

The generated code then correctly has this in the constructor which preserves the order 然后生成的代码在保留订单的构造函数中正确地具有此

contentModel = new SequenceContentModelEntity(
               new NamedContentModelEntity(XName.Get("AmazonOrderID", "")), 
               new NamedContentModelEntity(XName.Get("ActionType", "")), 
               new NamedContentModelEntity(XName.Get("CODCollectionMethod", "")), 
               new NamedContentModelEntity(XName.Get("AdjustedItem", "")));

You may also be able to do this manually by subclassing it youself, but I'm not sure how this would work with an xsd:choice. 您也可以通过自己进行子类化来手动执行此操作,但我不确定这对于xsd:choice是如何工作的。 This is described here but I haven't tested it. 这是在这里描述的,但我还没有测试过。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM