LinqToXml против LinqToSql

Попытка "разморозить" сериализованные объекты, которые были сохранены в файле XML:

В LinqToSQL я могу (с соответствующим образом оформленным классом) делать такие вещи:

   [Table(Name="Plants")]
   public class Plant
   {
      [Column(Name = "Id", IsPrimaryKey = true)]
      public int Id { get; set; }
      [Column(Name = "Genus")]
      public string Genus { get; set; }
      [Column(Name = "Species")]
      public string Species { get; set; }
      [Column(Name = "CommonName")]
      public string CommonName { get; set; }
      ...
    }

затем позже сделайте это:

 using (DataContext db = new DataContext(ConnectString))
 {
    plants = (
       from d in db.GetTable<Plant>()
       select d).ToList();
 }

а данные из таблицы SQL используются для заполнения списка<> объектов Plant.

Но с LinqToXML я не могу сделать этот трюк, вместо этого я должен сделать что-то вроде этого:

<!-- XML File -->
<Plants>
   <Plant>
      <Genus>Quercus</Genus>
      <Species>alba</Species>
      <CommonName>White Oak</CommonName>
   </Plant>
   ...
</Plants>

   // Class
   [DataContract]
   [XmlRoot("Plants")]
   public class Plant
   {
      [DataMember]
      public string Genus { get; set; }
      [DataMember]
      public string Species { get; set; }
      [DataMember]
      public string CommonName { get; set; }
      ...
    }

 // Code -- note: I already have the XML file in an XDocument called "doc"
 IEnumerable<XElement> items = (from item in doc.Descendants("Plant")
   where item.Element("Genus").Value.Equals("Quercus")
   select item);

 List<Plant> plants = new List<Plant>();
 foreach (XElement item in items)
 {
    Plant a = new Plant();
    a.Genus = item.Element("Genus").Value;
    a.Species = item.Element("Species").Value;
    XElement ex = item.Element("CommonName");
    if ((null == ex) || ex.IsEmpty) { } else { a.Example = ex.Value; }
    plants.Add(a);
 }

Учитывая, что я хотел бы сделать сериализацию / десериализацию универсальной, есть ли способ сделать это, не прибегая к рефлексии? Я могу использовать XmlSerializer, но это также включает в себя много возни с MemoryStreams и использования их как XmlWriter или XmlReaders, когда все, что я хочу, - это чтобы мой класс автоматически переходил в / из файла XML. Просто интересно, если я не смог соединить точки здесь...

1 ответ

Боюсь, вы смешиваете DataContracts и LinqToXML.

Вы можете использовать DataContracts для десериализации XML-документа в объект.

После десериализации вы сможете использовать LinqToObjects для запроса набора данных.

Попробуйте это:

[CollectionDataContract(Name = "Plants", ItemName = "Plant", Namespace = "")]
class Plants: List<Plant> { }

[DataContract(Name = "Plant", Namespace = "")]
class Plant
{
    [DataMember()]
    public string Genus { get; set; }

    [DataMember()]
    public string Species { get; set; }

    [DataMember()]
    public string CommonName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        using (var fs = new FileStream("Plants.xml", FileMode.Open))
        using (var reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()))
        {
            var ser = new DataContractSerializer(typeof(Plants));

            var plants = ser.ReadObject(reader) as Plants;

            foreach (var plant in plants)
                Console.WriteLine("{0}, {1}, {2}", plant.Genus, plant.Species, plant.CommonName);
        }

        Console.ReadKey();
    }
}
Другие вопросы по тегам