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