微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#DataTableDataRowCollection存储在一个临时文件中,而不是内存中?

如何解决C#DataTableDataRowCollection存储在一个临时文件中,而不是内存中?

| 我想通过将行存储在临时数据文件中而不是将行保留在内存中的方式,将DataTable替换为实现DaTarowCollection的自定义类。 我知道,与内存中的表相比,这会比较慢,但是我有时需要使用根本无法容纳ram(> 4GB数据)的表。我将丢弃该表并在运行结束时删除该临时文件。 表数据来自数据库查询。我知道我可以更改查询以减小返回的数据集的大小。那不是重点。关键是总是存在一些内存限制,我想选择使用慢速的临时文件,而不只是说“您不能这样做”。 是否有预写的类或方法?好像我在这里重塑车轮... 这是我的骨骼起点:
/// <summary>
/// like DataTable,but storing data in a file instead of memory
/// </summary>
public class FileBackedDataTable : DataTable,IIntegrationTest
{
    new public FileBackedDaTarowCollection Rows = null;

    // Summary:
    //     Initializes a new instance of the System.Data.DataTable class with no arguments.
    public FileBackedDataTable()
    {
        Rows = new FileBackedDaTarowCollection(this);
    }
}

/// <summary>
/// like a DaTarowCollection but data is stored in a file,not in memory
/// </summary>
public class FileBackedDaTarowCollection : ICollection,IEnumerable,Idisposable
{
    /// <summary>
    /// internally track each file record
    /// </summary>
    class recordInfo
    {
        public long recordPosition;
        public int recordLength;
        public int recordMaxLength;
        public long hash;
    }

    DataTable table;

    ArrayList rows = new ArrayList();

    public FileBackedDaTarowCollection(DataTable table)
    {
        this.table = table;
        openbackingFile(table);
    }

    public int Count 
    { 
        get { return rows.Count; } 
    }

    public void Clear()
    {
        rows.Clear();
        truncatebackingFile();
    }

    public DaTarow this[int index]
    {
        get
        {
            recordInfo info = (recordInfo)rows[index];
            return readRow(info);
        }
        set
        {
            writeRow(index,value);
        }
    }

    private void writeRow(int index,DaTarow value)
    {
        byte[] bytes = rowToBytes(value);
        recordInfo info = (recordInfo)rows[index];
        if (bytes.Length <= info.recordMaxLength)
        {
            info.recordLength = bytes.Length;
            info.hash = value.GetHashCode();
            writeBytes(info.recordPosition,bytes);
        }
        else
        {
            rows[index] = appendRow(bytes,value.GetHashCode());
        }
    }

    private DaTarow readRow(recordInfo recordInfo)
    {
        byte[] bytes = readBytes(recordInfo.recordPosition,recordInfo.recordLength);
        DaTarow row = bytesToRow(bytes);
        return row;
    }

    public void Add(DaTarow r)
    {
        byte[] bytes = rowToBytes(r);
        recordInfo info = appendRow(bytes,r.GetHashCode());
        rows.Add(info);
    }

    private recordInfo appendRow(byte[] bytes,long hash)
    {
        recordInfo info = new recordInfo();
        info.recordLength = bytes.Length;
        info.recordMaxLength = info.recordLength;
        info.recordPosition = appendBytes(bytes);
        info.hash = hash;
        return info;
    }
    

解决方法

您的计划中几乎有100%是不良设计。花一些时间进行重新设计,使用您的同伴数据库而不是FILE,它们是为了处理大数据而创建的。如果需要,您可以使用C#或其他语言(如果数据库允许)编写存储过程。 描述您想要处理数据的方式,您将获得真正问题的真实答案。它要么需要SQL查询,要么如果不能在SQL中完成,则可以肯定地以某种循环使用较小的数据大小来完成。     ,最近,我一直在寻找System.Data.SQLite来保留一些应用程序数据,而不是自己写一个。 如何使用SQLite创建临时文件并在其中加载旧数据?然后,您可以像本地文件一样使用它,并在咀嚼后将其删除。     ,您可以使用DataTable.WriteXml。但是我会支持其他人,最好首先限制从数据库中获得的记录。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。