点击或拖拽改变大小

Serializer 类

增量内容序列化器。
继承层次
SystemObject
  XPatchLibSerializer

命名空间:  XPatchLib
程序集:  XPatchLib (在 XPatchLib.dll 中) 版本:4.1.0.4
语法
C#
public class Serializer : IDisposable

Serializer 类型公开以下成员。

构造函数
  名称说明
公共方法Serializer
初始化 Serializer 类的新实例。
Top
方法
  名称说明
公共方法代码示例Combine(ITextReader, Object)
反序列化指定 ITextReader 包含的增量文档,并与 原始对象 进行数据合并。
公共方法代码示例Combine(ITextReader, Object, Boolean)
以可指定是否覆盖原始对象的方式反序列化指定 ITextReader 包含的增量文档,并与 原始对象 进行数据合并。
公共方法Dispose
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
公共方法代码示例Divide
使用指定的 ITextWriter 序列化指定的 原始对象 pOriValue 与 更新对象 pRevValue 间的增量内容。
公共方法RegisterType
Serializer 注册类型与主键集合。
Top
备注

比较同一对象类型的两个的实例间的差异内容,并产生增量的内容,使用指定的 文档写入器 ITextWriter 实例将增量内容写入文档, 也可以将增量的文档通过制定的文档读取器 ITextReader 实例反序列化并附加至原始的对象实例上。

使用 Divide 方法将原始对象与更新后对象之间差异内容的的公共字段和读/写属性转换为 增量数据。它不转换方法、索引器、私有字段或只读属性。

使用 Combine 方法将读取增量内容,并将增量数据与待合并的原始对象的数据合并,产生新的对象实例。(也可以使用重载方法,直接在原始对象上附加数据,这样将不会产生新的对象实例)

示例

简单对象增量序列化/反序列化示例

C#
using System;
using System.Text;
using XPatchLib;
using System.IO;

namespace XPatchLib.Example
{
    public class SimpleExample
    {
        public static void Main(string[] args)
        {
            Book OriBook = new Book()
            {
                ISBN = "0-385-50420-9",
                Name = "The Da Vinci Code",
                Author = new Author() {FirstName = "Dan", LastName = "Brown"}
            };

            Book RevBook = new Book()
            {
                ISBN = "0-385-50420-9",
                Name = "达芬奇密码",
                Author = new Author() {FirstName = "丹", LastName = "布朗"}
            };

            StringBuilder context = new StringBuilder();

            System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
            settings.Encoding = new UTF8Encoding(false);
            settings.OmitXmlDeclaration = true;
            settings.ConformanceLevel = System.Xml.ConformanceLevel.Document;
            Serializer serializer = new Serializer(typeof(Book));

            using (StringWriter strWriter = new StringWriter(context))
            {
                using (XmlTextWriter writer = new XmlTextWriter(strWriter))
                {
                    serializer.Divide(writer, OriBook, RevBook);
                }
            }

            Book NewBook = null;

            using (XmlTextReader reader = new XmlTextReader(new StringReader(context.ToString())))
            {
                NewBook = serializer.Combine(reader, OriBook, false) as Book;
            }

            Console.WriteLine(NewBook);
        }
    }

    [XPatchLib.PrimaryKey("ISBN")]
    public class Book
    {
        static string OUTPUT;

        static Book()
        {
            StringBuilder output = new StringBuilder();
            output.AppendLine("ISBN:{0}");
            output.AppendLine("Name:{1}");
            output.AppendLine("Author:{2} {3}");
            OUTPUT = output.ToString();
        }

        public string ISBN { get; set; }

        public string Name { get; set; }

        public Author Author { get; set; }

        public override string ToString()
        {
            return string.Format(OUTPUT, this.ISBN, this.Name, this.Author.FirstName, this.Author.LastName);
        }
    }

    public class Author
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

序列化增量内容如下所示:

context
<Book>
  <Author>
    <FirstName></FirstName>
    <LastName>布朗</LastName>
  </Author>
  <Name>达芬奇密码</Name>
</Book>

输出内容如下:

ISBN:0-385-50420-9
Name:达芬奇密码
Author:丹 布朗

较复杂的对象增量序列化示例

C#
using System;
using System.IO;
using System.Text;
using System.Xml;

namespace XPatchLib.Example
{
    public class ComplexObjCombineAndDivide
    {
        public static void Main()
        {
            var t = new ComplexObjCombineAndDivide();

            t.Divide("patch.xml");
            t.Combine("patch.xml");
        }

        private void Divide(string filename)
        {
            //原始对象
            var order = CreatePuchaseOrder();
            //更新后的对象
            var newOrder = CreatePuchaseOrder();

            //改变更新后对象的内容
            //由于直接修改了主键的内容,将被视为删除了原有主键为Widget S的对象,并新增了主键为Widget B的对象。
            newOrder.OrderedItems[0].ItemName = "Widget B";
            newOrder.OrderedItems[0].Description = "Big widget";
            newOrder.OrderedItems[0].UnitPrice = (decimal) 26.78;
            newOrder.OrderedItems[0].Quantity = 5;

            newOrder.ShipCost = (decimal) 12.51;

            //产生增量内容
            var serializer = new Serializer(typeof(PurchaseOrder));

            using (var writer = new XmlTextWriter(filename, new UTF8Encoding(false)))
            {
                serializer.Divide(writer, order, newOrder);
            }
        }

        private void OuputPuchaseOrder(PurchaseOrder order)
        {
            Console.WriteLine("OrderDate: " + order.OrderDate);
            ReadAddress(order.ShipTo, "Ship To:");
            Console.WriteLine("Items to be shipped:");
            foreach (var oi in order.OrderedItems)
                Console.WriteLine("\t" +
                                  oi.ItemName + "\t" +
                                  oi.Description + "\t" +
                                  oi.UnitPrice + "\t" +
                                  oi.Quantity + "\t" +
                                  oi.LineTotal);
            Console.WriteLine();
            Console.WriteLine("Subtotal:\t" + order.SubTotal);
            Console.WriteLine("Shipping:\t" + order.ShipCost);
            Console.WriteLine("Total:\t" + order.TotalCost);
        }

        private void Combine(string filename)
        {
            //合并增量内容至原始对象
            var serializer = new Serializer(typeof(PurchaseOrder));

            var oldOrder = CreatePuchaseOrder();
            PurchaseOrder newOrder = null;

            using (var fs = new FileStream(filename, FileMode.Open))
            {
                using (var reader = new XmlTextReader(fs))
                {
                    newOrder = (PurchaseOrder) serializer.Combine(reader, oldOrder);
                }
            }

            Console.WriteLine("OldOrder: ");
            OuputPuchaseOrder(oldOrder);
            Console.WriteLine("---------- ");
            Console.WriteLine("NewOrder: ");
            OuputPuchaseOrder(newOrder);
        }

        private void ReadAddress(Address a, string label)
        {
            Console.WriteLine(label);
            Console.WriteLine("\t" + a.Name);
            Console.WriteLine("\t" + a.Line1);
            Console.WriteLine("\t" + a.City);
            Console.WriteLine("\t" + a.State);
            Console.WriteLine("\t" + a.Zip);
            Console.WriteLine();
        }

        private PurchaseOrder CreatePuchaseOrder()
        {
            var result = new PurchaseOrder();

            var billAddress = new Address();
            billAddress.Name = "Teresa Atkinson";
            billAddress.Line1 = "1 Main St.";
            billAddress.City = "AnyTown";
            billAddress.State = "WA";
            billAddress.Zip = "00000";
            result.ShipTo = billAddress;
            result.OrderDate = DateTime.Now.ToLongDateString();

            var i1 = new OrderedItem();
            i1.ItemName = "Widget S";
            i1.Description = "Small widget";
            i1.UnitPrice = (decimal) 5.23;
            i1.Quantity = 3;

            OrderedItem[] items = {i1};
            result.OrderedItems = items;
            result.ShipCost = (decimal) 12.51;

            return result;
        }
        public class Address
        {
            public string City;
            public string Line1;
            public string Name;
            public string State;
            public string Zip;
        }

        [XPatchLib.PrimaryKey("ItemName")]
        public class OrderedItem
        {
            public string Description { get; set; }
            public string ItemName { get; set; }

            public decimal LineTotal
            {
                get { return UnitPrice * Quantity; }
            }

            public int Quantity { get; set; }
            public decimal UnitPrice { get; set; }
        }

        public class PurchaseOrder
        {
            public OrderedItem[] OrderedItems;
            public string OrderDate { get; set; }
            public decimal ShipCost { get; set; }
            public Address ShipTo { get; set; }

            public decimal SubTotal
            {
                get
                {
                    var subTotal = new decimal();
                    foreach (var oi in OrderedItems)
                        subTotal += oi.LineTotal;
                    return subTotal;
                }
            }

            public decimal TotalCost
            {
                get { return SubTotal + ShipCost; }
            }
        }

    }
}

序列化增量内容的 输出如下所示:

patch.xml
<?xml version="1.0" encoding="utf-8"?>
<PurchaseOrder>
  <OrderedItems>
    <OrderedItem Action="Remove" ItemName="Widget S" />
    <OrderedItem Action="Add">
      <Description>Big widget</Description>
      <ItemName>Widget B</ItemName>
      <Quantity>5</Quantity>
      <UnitPrice>26.78</UnitPrice>
    </OrderedItem>
  </OrderedItems>
</PurchaseOrder>

输出内容如下:

OldOrder:
OrderDate: 2017年3月12日
Ship To:
        Teresa Atkinson
        1 Main St.
        AnyTown
        WA
        00000

Items to be shipped:
        Widget S        Small widget    5.23    3       15.69

Subtotal:       15.69
Shipping:       12.51
Total:  28.20
----------
NewOrder:
OrderDate: 2017年3月12日
Ship To:
        Teresa Atkinson
        1 Main St.
        AnyTown
        WA
        00000

Items to be shipped:
        Widget B        Big widget      26.78   5       133.90

Subtotal:       133.90
Shipping:       12.51
Total:  146.41
版本信息

.NET Framework

支持版本:4.5, 4.0, 3.5, 2.0

.NET Standard

支持版本:2.0, 1.3, 1.0
参见