C# DataContractSerializer,将T的序列化附加到列表的序列化<;T>;

C# DataContractSerializer,将T的序列化附加到列表的序列化<;T>;,c#,serialization,deserialization,C#,Serialization,Deserialization,为了学习,我试图抽象出db访问,希望能够插入XML文件或JSON文件来提供数据访问 现在,我的类型具有以下构造函数 public XmlRepository(XElement root) { _rootElement = root; Load(); } 依赖项(根)由XmlContext类型提供,如下所示: private void Load() { if (!File.Exists(_fileName)) {

为了学习,我试图抽象出db访问,希望能够插入XML文件或JSON文件来提供数据访问

现在,我的类型具有以下构造函数

public XmlRepository(XElement root)
{
        _rootElement = root;
        Load();
}
依赖项(根)由XmlContext类型提供,如下所示:

private void Load()
    {
        if (!File.Exists(_fileName))
        {
            var schoolsXElement = new XElement("Schools");
            var gradesXElement = new XElement("Grades");
            var teachersXElement = new XElement("Teachers");
            var studentsXElement = new XElement("Students");

            _document = new XDocument(new XElement("DB"));
            _document.Root.Add(schoolsXElement);
            _document.Root.Add(gradesXElement);
            _document.Root.Add(teachersXElement);
            _document.Root.Add(studentsXElement);
            using (var fs = new FileStream(_fileName, FileMode.Create))
            {
                _document.Save(fs);
            }

        }
        else
        {
            _document = XDocument.Load(_fileName);
        }

        Schools = new XmlRepository<School>(_document.Root.Element("Schools"));
        Grades = new XmlRepository<Grade>(_document.Root.Element("Grades"));
        Teachers = new XmlRepository<Teacher>(_document.Root.Element("Teachers"));
        Students = new XmlRepository<Student>(_document.Root.Element("Students"));
    }
private void Load()
{
如果(!File.Exists(_fileName))
{
var schoolsXElement=新XElement(“学校”);
var gradesXElement=新的XElement(“等级”);
var teachersXElement=新的元素(“教师”);
var studentsXElement=新XElement(“学生”);
_文件=新的XDocument(新的XElement(“DB”);
_document.Root.Add(元素);
_document.Root.Add(gradesXElement);
_document.Root.Add(teachersXElement);
_document.Root.Add(studentsXElement);
使用(var fs=new FileStream(_fileName,FileMode.Create))
{
_文件保存(fs);
}
}
其他的
{
_document=XDocument.Load(_文件名);
}
Schools=新的XmlRepository(_document.Root.Element(“Schools”);
Grades=新的XmlRepository(_document.Root.Element(“Grades”);
教师=新的XmlRepository(_document.Root.Element(“教师”);
Students=newXMLRepository(_document.Root.Element(“Students”);
}
这些方法在
XmlRepository
中定义,当要将对数据的内存中视图的更改持久化到文件时,可以调用这些方法

private void Load()
    {
        if (!_rootElement.HasElements)
        {
            _persistentStorage = new List<T>();
            _memoryStorage = new List<T>();
            return;
        }

        var xmlDeserializer = new DataContractSerializer(typeof(List<T>));
        var obj = xmlDeserializer.ReadObject(_rootElement.FirstNode.CreateReader()) as List<T>;
        _persistentStorage = new List<T>(obj);
        _memoryStorage = new List<T>(obj);
    }

    private void Save()
    {
        var xmlSerializer = new DataContractSerializer(typeof(List<T>));
        var newAdditions = _memoryStorage.Except(_persistentStorage).ToList();
        _persistentStorage.AddRange(newAdditions);
        _rootElement.RemoveAll();
        using (var fs = _rootElement.CreateWriter())
        {
            xmlSerializer.WriteObject(fs, _persistentStorage);
        }
    }

private void Save()
    {
        var xmlSerializer = new DataContractSerializer(typeof(List<T>));
        var newAdditions = _memoryStorage.Except(_persistentStorage).ToList();
        _persistentStorage.AddRange(newAdditions);
        _rootElement.RemoveAll();
        using (var fs = _rootElement.CreateWriter())
        {
            xmlSerializer.WriteObject(fs, _persistentStorage);
        }
    }
private void Load()
{
if(!\u rootElement.HasElements)
{
_persistentStorage=新列表();
_memoryStorage=新列表();
返回;
}
var xmlDeserializer=新的DataContractSerializer(typeof(List));
var obj=xmlDeserializer.ReadObject(_rootElement.FirstNode.CreateReader())作为列表;
_persistentStorage=新列表(obj);
_memoryStorage=新列表(obj);
}
私有void Save()
{
var xmlSerializer=新的DataContractSerializer(typeof(List));
var newAdditions=_memoryStorage.Except(_persistentStorage.ToList();
_persistentStorage.AddRange(newAdditions);
_rootElement.RemoveAll();
使用(var fs=\u rootElement.CreateWriter())
{
WriteObject(fs,_persistentStorage);
}
}
私有void Save()
{
var xmlSerializer=新的DataContractSerializer(typeof(List));
var newAdditions=_memoryStorage.Except(_persistentStorage.ToList();
_persistentStorage.AddRange(newAdditions);
_rootElement.RemoveAll();
使用(var fs=\u rootElement.CreateWriter())
{
WriteObject(fs,_persistentStorage);
}
}
所有这些都呈现以下XML(来自测试运行)


0
126368128361
1.
126368128361
现在我的问题是save方法,我不喜欢删除存在的内容并用持久存储中的内容替换它。假设我在那里有10K个元素,并且只添加了1个,我会删除10K个元素,以便能够再添加1个


我该如何将其附加到XML中呢?

像XML这样的格式根本不利于附加,并且没有标准的XML序列化程序支持您想要做的事情

为了避免数据丢失的风险,您可以加载现有数据,添加新对象,将序列化到不同的文件,然后交换(重命名)文件

还有其他更友好的格式。例如,protobuf不会终止根元素,因此如果您有以下形式的消息:

message SomeRoot {
    repeated SomeType items = 1;
}

然后,您可以合并两个列表(一个在磁盘上,一个在内存中),只需在现有文件的末尾添加第二个列表(包含零个、一个或多个项);所以一个
SomeRoot
加上5个
SomeType
项目,再加上一个
SomeRoot
加上3个
SomeType
项目,与一个
SomeRoot
加上8个
SomeType
项目是一样的。

我想我别无选择,但有了内置的库,我的直觉告诉我,我想要实现的目标应该是可能的,但在我掌握的C#:技术的现阶段,情况并非如此
message SomeRoot {
    repeated SomeType items = 1;
}