如何将对象集合与复杂对象属性绑定

本文关键字:对象 复杂 属性 绑定 集合 | 更新日期: 2023-09-27 18:13:44

我正在尝试加载由Employee对象集合组成的XML数据。下面的函数适用于简单数据类型(如String和Int)的属性。我想知道如何导入复杂类型的数据类型。例如,

这个函数可以正常工作:

private void LoadData()
{
   XDocument employeesDoc = XDocument.Load("Employees.xml");
   List<Employee> data = (from employee in employeesDoc.Descendants("Employee")
      select new Employee
      {
         FirstName= employee.Attribute("FirstName").Value,
         LastName = employee.Attribute("LastName ").Value,
         PhoneNumber = employee.Attribute("PhoneNumber").Value
      }).ToList();
  Employees.ItemsSource = data;
}

下面是Employee类:

public class Employee
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string PhoneNumber { get; set; }
  public Department Department { get; set; }
}

这是Department类:

public class Department
{
  public int Id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
  public Employee Manager { get; set; }
}

那么,如果我的XML文件看起来像这样:

<Employees>
    <Employee FirstName="John" LastName="Summers" PhoneNumber="703-548-7841" Department="Finance"></Employee>
    <Employee FirstName="Susan" LastName="Hughey" PhoneNumber="549-461-7962" Department="HR"></Employee>

那么,如果Department是一个复杂对象,并且是XML文件中的字符串,我如何更改LoadData()函数以将其导入到Employee对象集合中呢?

如何将对象集合与复杂对象属性绑定

您有几个选项,但一切都取决于您如何获取XML(如何保存它)。(在我看来)最简单的阅读方法是:

XmlSerializer serializer = new XmlSerializer(typeof(YourType));
using (TextReader tr = new StreamReader("newSecret.xml"))
{
 YourType rrr = (YourType)serializer.Deserialize(tr);
}

更多示例:http://msdn.microsoft.com/en-us/library/he66c7f1.aspx

另一方面,如果你(出于某种原因)应该使用LINQ -看看这里:LINQ到XML:创建复杂的匿名类型这里http://blogs.msdn.com/b/xmlteam/archive/2007/03/24/streaming-with-linq-to-xml-part-2.aspx希望能有所帮助!

如果您可以在加载员工之前获得所有部门的列表,则可以将这些部门放入Dictionary,其中键为部门名称。然后,您可以为每个员工加载正确的部门:

var departmentsDict = departments.ToDictionary(d => d.Name);
XDocument employeesDoc = XDocument.Load("Employees.xml");
List<Employee> data = (from employee in employeesDoc.Descendants("Employee")
   select new Employee
   {
      FirstName= employee.Attribute("FirstName").Value,
      LastName = employee.Attribute("LastName ").Value,
      PhoneNumber = employee.Attribute("PhoneNumber").Value,
      Department = departmentsDict[employee.Attribute("Department").Value]
   }).ToList();
Employees.ItemsSource = data;

代码可能需要修改,这取决于如果部门不存在或者某人没有指定任何部门,您想要做什么。这段代码在这两种情况下都会抛出异常。

    using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
    public class Employee
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PhoneNumber { get; set; }
        public Department Department { get; set; }
    }
    public class Department
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public Employee Manager { get; set; }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            String filepath = @"C:''rrrr.xml";
            #region Create Test Data
            List<Employee> list = new List<Employee>();
            for (int i = 0; i < 5; i++)
            {
                list.Add(new Employee
                             {
                                 Department = new Department
                                                  {
                                                      Description = "bla bla description " + i,
                                                      Id = i,
                                                      Manager = null,
                                                      Name = "bla bla name " + i
                                                  },
                                 FirstName = "First name " + i,
                                 Id = i + i,
                                 LastName = "Last name " + i,
                                 PhoneNumber = Guid.NewGuid().ToString()
                             });
            } 
            #endregion
            #region Save XML
            XmlSerializer serializer = new XmlSerializer(typeof(List<Employee>));
            using (Stream fs = new FileStream(filepath, FileMode.Create))
            {
                using (XmlWriter writer = new XmlTextWriter(fs, Encoding.Unicode))
                {
                    serializer.Serialize(writer, list);
                }
            } 
            #endregion

            //Read from XML
            XmlDocument doc = new XmlDocument();
            doc.Load(filepath);
            List<Employee> newList = new List<Employee>();
            foreach (XmlNode node in doc.GetElementsByTagName("Employee"))
            {
                Employee ee = GetEmploee(node);
                newList.Add(ee);
            }
            //ta da
        }
        public static Employee GetEmploee(XmlNode node)
        {
            return node == null
                       ? new Employee()
                       : new Employee
                             {
                                 Department = GetDepartment(node["Department"]),
                                 FirstName = (node["FirstName"]).InnerText,
                                 LastName = (node["LastName"]).InnerText,
                                 Id = Convert.ToInt32((node["Id"]).InnerText),
                                 PhoneNumber = (node["PhoneNumber"]).InnerText
                             };
        }
        public static Department GetDepartment(XmlNode node)
        {
            return node == null
                       ? new Department()
                       : new Department
                             {
                                 Description = node["Description"].InnerText,
                                 Id = Convert.ToInt32(node["Id"].InnerText),
                                 Manager = GetEmploee(node["Manager"]),
                                 Name = node["Name"].InnerText
                             };
        }
    }
}