Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Datatable来自另一个Datatable的列的子集_C#_.net_Asp.net - Fatal编程技术网

C# Datatable来自另一个Datatable的列的子集

C# Datatable来自另一个Datatable的列的子集,c#,.net,asp.net,C#,.net,Asp.net,我有一个数据表,有17列和一堆数据 我找到了一个只有6列的数据表以及这6列的数据 所以我需要原始数据表的一个子集 如何循环遍历包含17列的原始datatable,最终得到一个只包含我想要的6列的datatable,以及这6列的相应数据?关于数据类型和列呢?这些是一样的吗?如果是,您可以创建 object[] row = new object[]{// Fill your rows manually}; 在填充之前,请创建 DataTable dt = new DataTable(); dt

我有一个数据表,有17列和一堆数据

我找到了一个只有6列的数据表以及这6列的数据

所以我需要原始数据表的一个子集


如何循环遍历包含17列的原始datatable,最终得到一个只包含我想要的6列的datatable,以及这6列的相应数据?

关于数据类型和列呢?这些是一样的吗?如果是,您可以创建

 object[] row = new object[]{// Fill your rows manually};
在填充之前,请创建

DataTable dt = new DataTable(); 
dt.Columns.Add("Title",typeof(string etc..));.....
最后

dt.Rows.Add(row);

在不知道这需要多普通的情况下,它真的只是

foreach (DataRow dr in dt.Rows)
{
  newDt.Rows.Add(dr["col1"],dr["col5"],etc);
}

就个人而言,我会避免创建DataTable的另一个实例

当然,这取决于您的情况,但如果这纯粹是为了可用性而不是为了安全性(即,在将敏感数据传输到某处之前,您不会尝试删除包含敏感数据的列),那么我将创建一个包装器对象,封装您要公开的列

使用包装器的好处是,如果您正在进行任何更新,那么您可以直接更新源表而不是副本。当然,这是否真的重要取决于你的情况

一个功能有限的简单示例:

public class MyFormOrPage
{
    void UsageExample()
    {
        DataTable allDataTable = new DataTable();
        // populate the data table with whatever logic ...

        // wrap the data table to expose only the Name, Address, and PhoneNumber columns
        var limitedDataTable = new DataTableWrapper(allDataTable, "Name", "Address", "PhoneNumber");

        // iterate over the rows
        foreach (var limitedDataRow in limitedDataTable)
        {
            // iterate over the columns
            for (int i = 0; i < limitedDataTable.ColumnCount; i++)
            {
                object value = limitedDataRow[i];
                // do something with the value ...
            }
        }

        // bind the wrapper to a control
        MyGridControl.DataSource = limitedDataTable;
    }
}

public class DataTableWrapper : IEnumerable<DataRowWrapper>
{
    private DataTable _Table;

    private string[] _ColumnNames;

    public DataTableWrapper(DataTable table, params string[] columnNames)
    {
        this._Table = table;

        this._ColumnNames = columnNames;
    }

    public int ColumnCount
    {
        get { return this._ColumnNames.Length; }
    }

    public IEnumerator<DataRowWrapper> GetEnumerator()
    {
        foreach (DataRow row in this._Table.Rows)
        {
            yield return new DataRowWrapper(row, this._ColumnNames);
        }
    }

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    #endregion

    // if you _really_ want to make a copy of the DataTable, you can use this method
    public DataTable CopyToDataTable()
    {
        DataTable copyTable = new DataTable();
        for (int index = 0; index < this._ColumnNames.Length; index++)
        {
            DataColumn column = this._Table.Columns[index];
            copyTable.Columns.Add(column);
        }
        foreach (DataRow row in this._Table.Rows)
        {
            DataRow copyRow = copyTable.NewRow();
            for (int index = 0; index < this._ColumnNames.Length; index++)
            {
                copyRow[index] = row[this._ColumnNames[index]];
            }
            copyTable.Rows.Add(copyRow);
        }
        return copyTable;
    }
}

// let's make this a struct, since potentially very many of these will be instantiated
public struct DataRowWrapper
{
    private DataRow _Row;

    private string[] _ColumnNames;

    public DataRowWrapper(DataRow row, params string[] columnNames)
    {
        this._Row = row;

        this._ColumnNames = columnNames;
    }

    // use this to retrieve column values from a row
    public object this[int index]
    {
        get { return this._Row[this._ColumnNames[index]]; }
        set { this._Row[this._ColumnNames[index]] = value; }
    }

    // just in case this is still needed...
    public object this[string columnName]
    {
        get { return this._Row[columnName]; }
        set { this._Row[columnName] = value; }
    }
}
公共类MyFormOrPage
{
void UsageExample()
{
DataTable allDataTable=新DataTable();
//用任何逻辑填充数据表。。。
//包装数据表以仅显示名称、地址和电话号码列
var limitedDataTable=新的DataTableWrapper(allDataTable,“名称”、“地址”、“电话号码”);
//在行上迭代
foreach(limitedDataTable中的var limitedDataRow)
{
//在列上迭代
对于(int i=0;i
最初是如何填充数据表的?如果您是从数据库中填充它,那么通过SQL SELECT命令应该很容易按照您的要求执行。我相信这里有一个输入错误-您想要的是dt.Rows[“col5”],而不是dr,不是吗?或者,你也可以让dr[“col1”]、dr[“col5”]…@Melanie是的,我认为后者是正确的,以及我写这篇文章时的想法(虽然是三年前,我真的不记得回答过这个问题了,哈哈)…编辑我的答案以反映你的更正
Private Function createSmallCopyofExistingTable(ByVal SourceTable As DataTable) As DataTable
    Dim newTable As DataTable = New DataTable()

    'Copy Only 6 columns from the datatable 
    Dim ColumnsToExport() As String = {"ID", "FirstName", "LastName", "DateOfBirth", "City", "State"}

    newTable = SourceTable.DefaultView.ToTable("tempTableName", False, ColumnsToExport)



    Return newTable
End Function