在一个DataTable或数据集将其再利用LINQ的结果

在一个DataTable或数据集将其再利用LINQ的结果

本文介绍了在一个DataTable或数据集将其再利用LINQ的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

*的强大的文本的*感谢Tim谁给我提供的code低于本其他职位:Join/merge两人在asp.net Excel文件,并在GridView控件显示出来。

我在这个新职位的问题是:
我怎么可以重复使用或LINQ结果添加到数据集或datatabe这样我就可以查询新表,而不是两个单独的表? join关键字给了我加入这两个表的可能性。现在,我想用这个表要在其上运行其他查询。

我希望我的问题是有道理的。如果您需要更多的信息,请让我知道。

 的DataSet DS =新的DataSet(股票);
使用(VAR的DbConnection =新的OleDbConnection(CONNSTRING))
使用(VAR的DbCommand =新的OleDbCommand(SELECT * FROM [工作表Sheet1 $]的DbConnection))
使用(VAR DA =新OleDbDataAdapter的(的DbCommand))
{
    da.Fill(DSHWTypes);
}使用(VAR的DbConnection =新的OleDbConnection(stockConn))
使用(VAR的DbCommand =新的OleDbCommand(SELECT * FROM [Stock_voorlopig $]的DbConnection))
使用(VAR DA =新OleDbDataAdapter的(的DbCommand))
{
    da.Fill(DS,股票);
}VAR在ds.Tables [HWTypes] =加盟从舍入类型。AsEnumerable()
             在ds.Tables [股票]加入rStock。AsEnumerable()
             在rType.Field<串GT(产品ID)等于rStock.Field<串GT(型号封装)
             新选择
             {
                 的ProductID = rType.Field<串GT(产品ID)
                 //添加您需要这里的其他列
             };
GridView1.DataSource =加入;
GridView1.DataBind();

编辑1:

我试图做这样的事情:

 私有静态数据表JoinDataTablesWithLinq()
{ //从上面的code休息
 返回joined.CopyToDataTable();
}

但我得到这个错误:

 类型'AnonymousType#1不能用作泛型类型或方法的类型参数'T' 'System.Data.DataTableExtensions.CopyToDataTable<T>(System.Collections.Generic.IEnumerable<T>)'.有一个从AnonymousType#1到的System.Data.DataRow'隐式引用转换。

任何帮助吗?


解决方案
private static DataTable JoinDataTablesWithLinq()
{

 //rest of the code from above
 return joined.CopyToDataTable();
}

You cannot create a DataTable "on the fly". You have selected an anonymous type which is not a IEnumerable<DataRow> which you need to use CopyToDataTable. So you either have to use a custom class and fill a List<MyClass> with all properties you need to persist it or you have to create a DataTable with all necessary DataColumns of the anonymous type and fill that.

You see that it's not that easy. There's one dynamic approach though. But that requires reflection, therefore it's not efficient at all.

Here we go... (extract of my other answer)

You could build your own CopyToDataTable that takes any kind of IEnumerable(not only DataRow)and returns a new DataTable:

Here is the implementation (with help of MSDN):

public class ObjectShredder<T> {
    private System.Reflection.FieldInfo[] _fi;
    private System.Reflection.PropertyInfo[] _pi;
    private System.Collections.Generic.Dictionary<string, int> _ordinalMap;
    private System.Type _type;

    // ObjectShredder constructor.
    public ObjectShredder() {
        _type = typeof(T);
        _fi = _type.GetFields();
        _pi = _type.GetProperties();
        _ordinalMap = new Dictionary<string, int>();
    }

    /// <summary>
    /// Loads a DataTable from a sequence of objects.
    /// </summary>
    /// <param name="source">The sequence of objects to load into the DataTable.</param>
    /// <param name="table">The input table. The schema of the table must match that
    /// the type T.  If the table is null, a new table is created with a schema
    /// created from the public properties and fields of the type T.</param>
    /// <param name="options">Specifies how values from the source sequence will be applied to
    /// existing rows in the table.</param>
    /// <returns>A DataTable created from the source sequence.</returns>
    public DataTable Shred(IEnumerable<T> source, DataTable table, LoadOption? options) {
        // Load the table from the scalar sequence if T is a primitive type.
        if (typeof(T).IsPrimitive) {
            return ShredPrimitive(source, table, options);
        }

        // Create a new table if the input table is null.
        if (table == null) {
            table = new DataTable(typeof(T).Name);
        }

        // Initialize the ordinal map and extend the table schema based on type T.
        table = ExtendTable(table, typeof(T));

        // Enumerate the source sequence and load the object values into rows.
        table.BeginLoadData();
        using (IEnumerator<T> e = source.GetEnumerator()) {
            while (e.MoveNext()) {
                if (options != null) {
                    table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options);
                } else {
                    table.LoadDataRow(ShredObject(table, e.Current), true);
                }
            }
        }
        table.EndLoadData();

        // Return the table.
        return table;
    }

    public DataTable ShredPrimitive(IEnumerable<T> source, DataTable table, LoadOption? options) {
        // Create a new table if the input table is null.
        if (table == null) {
            table = new DataTable(typeof(T).Name);
        }

        if (!table.Columns.Contains("Value")) {
            table.Columns.Add("Value", typeof(T));
        }

        // Enumerate the source sequence and load the scalar values into rows.
        table.BeginLoadData();
        using (IEnumerator<T> e = source.GetEnumerator()) {
            Object[] values = new object[table.Columns.Count];
            while (e.MoveNext()) {
                values[table.Columns["Value"].Ordinal] = e.Current;

                if (options != null) {
                    table.LoadDataRow(values, (LoadOption)options);
                } else {
                    table.LoadDataRow(values, true);
                }
            }
        }
        table.EndLoadData();

        // Return the table.
        return table;
    }

    public object[] ShredObject(DataTable table, T instance) {

        FieldInfo[] fi = _fi;
        PropertyInfo[] pi = _pi;

        if (instance.GetType() != typeof(T)) {
            // If the instance is derived from T, extend the table schema
            // and get the properties and fields.
            ExtendTable(table, instance.GetType());
            fi = instance.GetType().GetFields();
            pi = instance.GetType().GetProperties();
        }

        // Add the property and field values of the instance to an array.
        Object[] values = new object[table.Columns.Count];
        foreach (FieldInfo f in fi) {
            values[_ordinalMap[f.Name]] = f.GetValue(instance);
        }

        foreach (PropertyInfo p in pi) {
            values[_ordinalMap[p.Name]] = p.GetValue(instance, null);
        }

        // Return the property and field values of the instance.
        return values;
    }

    public DataTable ExtendTable(DataTable table, Type type) {
        // Extend the table schema if the input table was null or if the value
        // in the sequence is derived from type T.
        foreach (FieldInfo f in type.GetFields()) {
            if (!_ordinalMap.ContainsKey(f.Name)) {
                // Add the field as a column in the table if it doesn't exist
                // already.
                DataColumn dc = table.Columns.Contains(f.Name) ? table.Columns[f.Name]
                    : table.Columns.Add(f.Name, f.FieldType);

                // Add the field to the ordinal map.
                _ordinalMap.Add(f.Name, dc.Ordinal);
            }
        }
        foreach (PropertyInfo p in type.GetProperties()) {
            if (!_ordinalMap.ContainsKey(p.Name)) {
                // Add the property as a column in the table if it doesn't exist
                // already.
                DataColumn dc = table.Columns.Contains(p.Name) ? table.Columns[p.Name]
                    : table.Columns.Add(p.Name, p.PropertyType);

                // Add the property to the ordinal map.
                _ordinalMap.Add(p.Name, dc.Ordinal);
            }
        }

        // Return the table.
        return table;
    }
}

Now you can add these extensions:

public static class CustomLINQtoDataSetMethods {
    public static DataTable CopyToDataTable<T>(this IEnumerable<T> source) {
        return new ObjectShredder<T>().Shred(source, null, null);
    }

    public static DataTable CopyToDataTable<T>(this IEnumerable<T> source,
                                                DataTable table, LoadOption? options) {
        return new ObjectShredder<T>().Shred(source, table, options);
    }
}

Voilà! Now CopyToDataTable works with any kind of IEnumerable<T> :)

这篇关于在一个DataTable或数据集将其再利用LINQ的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 03:11