首页 > 解决方案 > 使用 DataContractSerializer 将具有交叉引用的对象反序列化到两个列表中

问题描述

起初 - 对不起我的英语。我知道“贷款”和“出借人”不是这个词。

我有两节课:

[DataContract(IsReference = true)]
    public class Person {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string IDK { get; set; }
        [DataMember]
        public ObservableCollection<Book> CurrentLoanedBooks { get; set; } = new ObservableCollection<Book>();

        public Person() { 
        }

        public Person(string name, string idk) {
            this.Name = name;
            this.IDK = idk;
        }
    }
[DataContract(IsReference = true)]
public class Book {
        [DataMember]
        public string Title { get; set; }
        [DataMember]
        public string IDC { get; set; }
        [DataMember]
        public Person Loaner { get; set; }

        public Book() {
        }

        public Book(string title, string idc) {
            this.Title = title;
            this.IDC = idc;
        }
    }

我的主班也有两个列表:

private ObservableCollection<Book> Books { get; set; } = new ObservableCollection<Book>();
private ObservableCollection<Person> People { get; set; } = new ObservableCollection<Person>();

我的程序将这些集合绑定到 WPF 中的 DataGrid。当程序运行时,用户可以输入新书和新人。问题是序列化。我设法制作了一个DataContractSerializer没有任何错误的输出。但是,我无法加载数据。反序列化产生良好的输出,我加载了两个列表。但我不知道如何将这两个列表中的对象与它们自身链接起来。

反序列化不链接任何对象。反序列化后,当我尝试查看 Book's Loaner 时,我看不到在 List 中加载和创建的正确 Loaner。

当我将 Book Loaner 保存在一个变量中,并将适当的 Person 保存在第二个变量中时,对象引用不匹配。

Console.WriteLine(object.ReferenceEquals(loaner2, loaner1));
// False

我想以某种方式反序列化它,将这些对象与其自身“链接”。

序列化和反序列化:

private void SaveButton_Click(object sender, RoutedEventArgs e) {
    DataContractSerializer b_ser = new DataContractSerializer(typeof(ObservableCollection<Book>));
    DataContractSerializer p_ser = new DataContractSerializer(typeof(ObservableCollection<Person>));

    using(FileStream b_fs = File.OpenWrite("books.xml"))
    using(FileStream p_fs = File.OpenWrite("people.xml")) {
        p_ser.WriteObject(b_fs, this.Books);
        p_ser.WriteObject(p_fs, this.People);
    }
}
private void LoadButton_Click(object sender, RoutedEventArgs e) {
    DataContractSerializer b_ser = new 
    DataContractSerializer(typeof(ObservableCollection<Book>));
    DataContractSerializer p_ser = new 
    DataContractSerializer(typeof(ObservableCollection<Person>));

    try {
        using (FileStream b_fs = File.OpenRead("books.xml"))
        using (FileStream p_fs = File.OpenRead("people.xml")) {
                this.Books = b_ser.ReadObject(b_fs) as ObservableCollection<Book>;
                this.People = p_ser.ReadObject(p_fs) as ObservableCollection<Person>;
        }
    } catch (...) {
        // Setting default values if some trouble
    }
}

标签: c#.netxml-serializationdatacontractserializer

解决方案


推荐阅读