2009-11-05 7 views
0

Essayer de « dégel » des objets sérialisés qui ont été stockés dans un fichier XML:LinqToXml vs LinqToSql

En LinqToSQL, je peux (avec une classe convenablement décorée) faire ce genre de chose:

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

puis faire plus tard ceci:

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

et les données de la table SQL sont utilisées pour remplir une liste <> des objets végétaux.

Mais avec LinqToXML je ne peux pas sembler faire ce tour, au lieu que je dois faire quelque chose comme ceci:

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

Étant donné que je voudrais faire cette sérialisation/désérialisation objectif général, est-il manière de le faire sans recourir à la réflexion? Je peux utiliser le XmlSerializer, mais cela aussi implique beaucoup de choses avec MemoryStreams et les utiliser comme XmlWriter ou XmlReaders quand tout ce que je veux faire est de rendre ma classe automagiquement aller/partir d'un fichier XML. Je me demande simplement si je ne parviens pas à connecter les points ici ...

Répondre

1

Je crains que vous mélangez DataContracts et LinqToXML.

Vous pouvez utiliser DataContracts pour désérialiser un document XML vers un objet. Après la désérialisation, vous devriez pouvoir utiliser LinqToObjects pour interroger l'ensemble de données.

pour cette solution:

[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(); 
    } 
}