Сохранение порядка в последовательности выбора (LINQ To XSD) - PullRequest
7 голосов
/ 28 октября 2009

Учитывая следующий пример XML, мы могли бы представить схему, определяющую Root как содержащую последовательность несвязанного числа вариантов выбора между Type1 и Type2.

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

Я тестирую миграцию с помощью инструмента XSD.exe, который, хотя и добавляет безопасность типов, вызывает много небольших неприятностей. Инструмент XSD в этом случае просто создает в Root массив типа System.Object, и вам необходимо выяснить, какие типы объектов (Type1 или Type2) находятся там. Это не совсем элегантно, но, по крайней мере, вы сохраняете порядок.

Проблема в том, что когда LINQ to XSD создает объекты, он определяет Root как имеющий два независимых списка Type1 и Type2. Это здорово, потому что это типобезопасно, но теперь я, похоже, теряю порядок элементов. Я построил LINQ to XSD из исходного кода на codeplex.

Как использовать LINQ to XSD, как сохранить порядок этих элементов?

Ответы [ 2 ]

2 голосов
/ 25 декабря 2009

Как насчет создания оболочки вокруг 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 методы, которые будут оборачивать запросы.

1 голос
/ 12 марта 2014

Linq2Xsd срабатывает только на последовательности, когда есть элемент xsd: choice.

К счастью, я смог удалить xsd: выбор для Amazon XSD , который я использую (я просто не использовал MerchantOrderID), что позволило правильно сохранить последовательность в ToString() для XML.

            <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 :. Это описано здесь , но я не проверял это.

...