C# 用XML存储关系数据

C# 用XML存储关系数据,c#,xml,C#,Xml,我想知道用XML存储关系数据结构的最佳实践是什么。特别是,我想知道强制执行节点顺序的最佳实践。例如,假设我有三个对象:学校、课程、和学生,它们的定义如下: class School { List<Course> Courses; List<Student> Students; } class Course { string Number; string Description; } class Student { string

我想知道用XML存储关系数据结构的最佳实践是什么。特别是,我想知道强制执行节点顺序的最佳实践。例如,假设我有三个对象:
学校
课程
、和
学生
,它们的定义如下:

class School
{
    List<Course> Courses;
    List<Student> Students;
}

class Course
{
    string Number;
    string Description;
}

class Student
{
    string Name;
    List<Course> EnrolledIn;
}
班级学校
{
列出课程;
列出学生名单;
}
班级课程
{
字符串编号;
字符串描述;
}
班级学生
{
字符串名;
登记的名单;
}
我会将这种数据结构存储在XML中,如下所示:

<School>
    <Courses>
        <Course Number="ENGL 101" Description="English I" />
        <Course Number="CHEM 102" Description="General Inorganic Chemistry" />
        <Course Number="MATH 103" Description="Trigonometry" />
    </Courses>
    <Students>
        <Student Name="Jack">
            <EnrolledIn>
                <Course Number="CHEM 102" />
                <Course Number="MATH 103" />
            </EnrolledIn>
        </Student>
        <Student Name="Jill">
            <EnrolledIn>
                <Course Number="ENGL 101" />
                <Course Number="MATH 103" />
            </EnrolledIn>
        </Student>
    </Students>
</School>

使用这种方式排序的XML,我可以首先解析
课程
。然后,当我解析
学生
时,我可以在
学校.课程
列表中查找
注册
中列出的每个
课程
(通过其
编号
)。这将为我提供一个对象引用,以添加到
Student
中的
EnrolledIn
列表中。但是,如果
学生
课程
之前,则不可能进行此类查找以获取对象引用。(自
学校以来。课程
尚未填充。)

那么,用XML存储关系数据的最佳实践是什么呢? -我是否应该强制要求
课程
必须始终在
学生
之前? -当我遇到一个我还没有见过的对象时,我是否应该容忍任何排序并创建一个存根
课程
对象?(待以后最终达到
课程的定义时展开。)
-是否有其他方法可以将对象持久化/加载到XML或从XML加载对象?(我目前正在所有业务对象上实现
Save
Load
方法,并使用
System.Xml.XmlDocument
及其关联类手动执行所有这些操作。)


我习惯于使用SQL之外的关系数据,但这是我第一次尝试用XML存储非平凡的关系数据结构。如果您能就我应该如何继续提供任何建议,我们将不胜感激。

根据经验,XML并不是存储关系数据的最佳方法。你调查过了吗?你有选择吗

如果不这样做,一种安全的方法是为XML提供一个严格的DTD,并以这种方式实施。正如您所建议的,您还可以保留所创建对象的散列。这样,如果一个学生创建了一门课程,你就可以保留该课程,以便在点击标记时进行更新


还请记住,您可以使用XPath查询直接访问特定节点,因此无论在XML文档中的位置如何,都可以首先强制解析课程。(多亏了dacracot,给出了更完整的答案)

根据经验,XML并不是存储关系数据的最佳工具。你调查过了吗?你有选择吗

如果不这样做,一种安全的方法是为XML提供一个严格的DTD,并以这种方式实施。正如您所建议的,您还可以保留所创建对象的散列。这样,如果一个学生创建了一门课程,你就可以保留该课程,以便在点击标记时进行更新


还请记住,您可以使用XPath查询直接访问特定节点,因此无论在XML文档中的位置如何,都可以首先强制解析课程。(多亏了dacracot,答案更完整)

虽然您可以使用指定子元素的顺序,但通过要求子对象按特定顺序排列,您的系统灵活性会降低(即,使用记事本更新更困难)

最好的办法是解析出所有数据,然后执行需要执行的操作。不要在解析过程中进行操作


显然,XML及其背后数据的设计排除了将单个POCO序列化为XML的可能性。您需要控制序列化和反序列化逻辑,以便将对象解除挂钩并重新挂钩在一起

我建议创建一个自定义序列化程序来构建这个对象图的xml表示。因此,它不仅可以控制序列化的顺序,还可以处理节点不符合预期顺序的情况。您可以执行其他操作,例如添加自定义属性以用于将对象链接在一起,而这些对象在被序列化的对象上不作为公共属性存在


创建xml非常简单,只需在对象上迭代几次,建立Xelement集合,并以xml的形式表示对象。完成后,您可以将它们缝合到一个XDocument中,并从中获取xml。您可以在xml的反面进行多次传递,以重新创建对象图并还原所有引用。

虽然您可以使用指定子元素的顺序,但通过要求子对象以特定顺序出现,会降低系统的灵活性(即,更难使用记事本进行更新)

最好的办法是解析出所有数据,然后执行需要执行的操作。不要在解析过程中进行操作


显然,XML及其背后数据的设计排除了将单个POCO序列化为XML的可能性。您需要控制序列化和反序列化逻辑,以便将对象解除挂钩并重新挂钩在一起

我建议创建一个自定义序列化程序来构建这个对象图的xml表示。因此,它不仅可以控制序列化的顺序,还可以处理节点不符合预期顺序的情况。您可以执行其他操作,例如添加自定义属性以用于将对象链接在一起,而这些对象在被序列化的对象上不作为公共属性存在

创建xml非常简单,只需在对象上迭代几次,建立Xelement集合,并以xml的形式表示对象。完成后,您可以将它们缝合到一起
<School>
    <Students>
        <Student Name="Jack">
            <EnrolledIn>
                <Course Number="CHEM 102" Description="General Inorganic Chemistry" />
                <Course Number="MATH 103" Description="Trigonometry" />
            </EnrolledIn>
        </Student>
        <Student Name="Jill">
            <EnrolledIn>
                <Course Number="ENGL 101" Description="English I" />
                <Course Number="MATH 103" Description="Trigonometry" />
            </EnrolledIn>
        </Student>
    </Students>
</School>