C# 用C动态序列化大量对象,而不是一次序列化所有对象?

C# 用C动态序列化大量对象,而不是一次序列化所有对象?,c#,xml,oop,serialization,C#,Xml,Oop,Serialization,我创建了两个类来表示关系数据结构(父子结构)。下面是XML表示的一个示例,至今为止,您可以了解我的意思 <BillingFile> <Account> <acctnum>122344231414</acctnum> <adjustments>34.44</adjustments> <Charges> <lineitem>

我创建了两个类来表示关系数据结构(父子结构)。下面是XML表示的一个示例,至今为止,您可以了解我的意思

<BillingFile>
    <Account>
      <acctnum>122344231414</acctnum>
      <adjustments>34.44</adjustments>
      <Charges>
        <lineitem>
          <chargetype>PENALTY</chargetype>
          <amount>40.50</amount>
          <ratecode>E101</ratecode>
        </lineitem>
        <lineitem>
          <chargetype>LATE CHARGE</chargetype>
          <amount>445.35</amount>
          <ratecode>D101</ratecode>
        </lineitem>
      </Charges>
    </Account>
</BillingFile>

122344231414
34.44
处罚
40.50
E101
滞纳金
445.35
D101
我对我的应用程序所做的是通过一个大的文本文件进行解析,其中可能有超过50000个帐户。每次读取帐户时,我将创建一个包含父对象等的“帐户”对象。最终目标是能够创建一个XML文件,其中包含从创建的对象序列化的所有帐户信息

我看到的问题是,如果我将所有这些对象都存储在内存中,它将导致性能问题,因为它在那些50k+记录文件中运行

我想知道的是,有没有一种方法可以顺序序列化C#中的对象,而不是一次全部序列化

我在谷歌上搜索了一下,似乎.NET内置的序列化方法是一种一劳永逸的交易。有更好的办法吗

我宁愿避免执行任何中间步骤,如将数据存储在数据库中,因为修改代码比处理一堆表和JOIN语句更容易

想法

我看到的问题是,如果我将所有这些对象都存储在内存中,它将导致性能问题,因为它在那些50k+记录文件中运行

先测试一下。50k*1kB仍然只有50MB

不要解决你没有的问题

我看到的问题是,如果我将所有这些对象都存储在内存中,它将导致性能问题,因为它在那些50k+记录文件中运行

先测试一下。50k*1kB仍然只有50MB


不要解决你没有的问题

您可以创建自己的帐户对象,该对象将采用XElement并从该节点读取数据,例如:

public class Account
{
    XElement self;
    public Account(XElement account)
    { 
        if(null == account)
            self = new XElement("Account");
        else
            self = account; 
    }

    public int Number
    {
        get { return self.Get("acctnum", 0); }
        set { self.Set("acctnum", value, false); }
    }

    public Charges Charges { get { return new Charges(self.GetElement("Charges")); } }
}
我使用来获取处理空节点/默认值的信息,如上面所述,0是数字get的默认int值。如果不存在,则
GetElement()
会创建一个新的Charges节点

您将需要创建可枚举费用类和LineItem类,但您只需要根据需要创建所需的内容

您可以使用XPath查找填充帐户,如:

Account account = new Account(
    root.XPathSelectElement("Account[acctnum='"+ someAccount + "']"));

XPath是使用System.Xml.XPath通过
找到的。您可以创建自己的帐户对象,该对象将接受XElement并从该节点读取数据,例如:

public class Account
{
    XElement self;
    public Account(XElement account)
    { 
        if(null == account)
            self = new XElement("Account");
        else
            self = account; 
    }

    public int Number
    {
        get { return self.Get("acctnum", 0); }
        set { self.Set("acctnum", value, false); }
    }

    public Charges Charges { get { return new Charges(self.GetElement("Charges")); } }
}
我使用来获取处理空节点/默认值的信息,如上面所述,0是数字get的默认int值。如果不存在,则
GetElement()
会创建一个新的Charges节点

您将需要创建可枚举费用类和LineItem类,但您只需要根据需要创建所需的内容

您可以使用XPath查找填充帐户,如:

Account account = new Account(
    root.XPathSelectElement("Account[acctnum='"+ someAccount + "']"));
XPath是使用System.Xml通过
找到的。XPath

接受一个参数。您可以将
XmlReader
放在
标记处,然后在那里调用
XmlSerializer

public IEnumerable<Account> ReadAccounts(TextReader source)
{
    var ser = new XmlSerializer(typeof(Account));

    using (var reader = XmlReader.Create(source))
    {
        if (!reader.IsStartElement("BillingFile"))
        {
            yield break;
        }

        reader.Read();

        while (reader.MoveToContent() == XmlNodeType.Element)
        {
            yield return (Account) ser.Deserialize(reader);
        }
    }
}
接受一个参数。您可以将
XmlReader
放在
标记处,然后在那里调用
XmlSerializer

public IEnumerable<Account> ReadAccounts(TextReader source)
{
    var ser = new XmlSerializer(typeof(Account));

    using (var reader = XmlReader.Create(source))
    {
        if (!reader.IsStartElement("BillingFile"))
        {
            yield break;
        }

        reader.Read();

        while (reader.MoveToContent() == XmlNodeType.Element)
        {
            yield return (Account) ser.Deserialize(reader);
        }
    }
}

@EdRoper我添加了一个
会计撰稿人
你是我的新英雄。基于推送的模型工作完美,大大加快了我的应用程序。谢谢@EdRoper我添加了一个
会计撰稿人
你是我的新英雄。基于推送的模型工作完美,大大加快了我的应用程序。谢谢