Десериализовать XML в объект Linq to SQL - PullRequest
3 голосов
/ 17 января 2010

Мне нужно прочитать данные XML из внешних систем, которые будут примерно отформатированы следующим образом:

<Applicant>
  <FirstName>John</FirstName>
  <LastName>Smith</LastName>
  <Address>12 Main St</Address>
</Applicant>

Это прямое сопоставление моего класса Linq to SQL Applicant, за исключением нескольких свойств.

Каков наилучший способ десериализации xml в объект Linq to SQL, чтобы я мог затем вставить его непосредственно в базу данных? Я также хотел бы проверить входящий XML и обработать определенные ошибки, если это возможно.

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 17 января 2010

Если это прямая карта, вы должны просто иметь возможность использовать ее напрямую, если типы доступны как public и имеют открытые конструкторы без параметров, а свойства (включая списки) - get / set.

Если вам нужно настроить имена, есть конструктор XmlSerializer, который позволяет вам указать все атрибуты. Это идеально подходит для вашего сценария, но вы должны кэшировать и повторно использовать сериализатор, если вы используете эту перегрузку конструктора, в противном случае вы потеряете память (динамические сборки не будут собраны).

Вот полный пример, который удаляет одно свойство (XmlIgnore), заменяет другое на атрибут и оставляет третье в качестве элемента.

using System;
using System.IO;
using System.Xml.Serialization;
public class Foo
{
    public int A { get; set; }
    public string B { get; set; }
    public int C { get; set; }
}
static class Program
{
    static readonly XmlSerializer serializer;
    static Program()
    {
        XmlAttributeOverrides or = new XmlAttributeOverrides();
        or.Add(typeof(Foo), "A", new XmlAttributes { // change to an attrib
            XmlAttribute = new XmlAttributeAttribute("tweaked")
        });
        or.Add(typeof(Foo), "B", new XmlAttributes {
            XmlIgnore = true // turn this one off
        });
        // leave C as a default named element
        serializer = new XmlSerializer(typeof(Foo), or);
    }
    static void Main()
    {
        Foo foo = new Foo { A = 123, B = "def", C = 456 }, clone;
        string xml;
        using (StringWriter sw = new StringWriter())
        {
            serializer.Serialize(sw, foo);
            xml = sw.ToString();
        }
        using (StringReader sr = new StringReader(xml)) {
            clone = (Foo)serializer.Deserialize(sr);
        }
        Console.WriteLine(xml);
        Console.WriteLine();
        Console.WriteLine(clone.A);
        Console.WriteLine(clone.B);
        Console.WriteLine(clone.C);
    }
}

Также обратите внимание, что если вам нужно только что-то изменить на уровне type (например, [XmlInclude]), то вы можете сделать это с помощью partial class, который генерирует LINQ-to-SQL; например:

namespace My.Dal.Namespace {
    // add a type attribute to SomeEntity
    [XmlInclude(typeof(SomeDerivedEntity))]
    partial class SomeEntity { } 
}
0 голосов
/ 28 апреля 2010

Это намного проще.

Сначала используйте DataContractSerializer для сериализации ваших объектов LinqToXml. Это возвращает байтовый массив. С Encoding.UTF8.GetString (байтовый массив из DataContractSerializer) вы получаете xml представление ваших сущностей ...

Надеюсь, это поможет

0 голосов
/ 17 января 2010

Для проверки вам нужна XML-схема для этих поступающих XML-файлов - вы можете довольно легко создать ее с помощью инструмента xsd.exe в вашем каталоге Windows SDK, который берет XML-файл и превращает его в xsd (XML-схема) файл.

Если у вас уже есть класс, который в основном соответствует этому XML, да, возможно, проще всего было бы просто десериализовать его в Applicant класс:

XmlSerializer ser = new XmlSerializer(typeof(Applicant));
StreamReader sr = new StreamReader(.....); // depends on where you get your XML from
Applicant result = (Applicant)ser.Deserialize(sr);

Это должно заполнить ваш Applicant объект теми свойствами, которые приходят из XML - это будет работать до тех пор, пока вы не оставите все обязательные свойства пустыми (и не сможете предоставить действительное значение по умолчанию) и если у вас нет каких-либо несовпадений типов в ваших сопоставлениях (например, попытка десериализации строки в свойство INT или что-то в этом роде).

...