【问题标题】:Linq join 2 datatables that share a column and put result in new datatableLinq 连接 2 个共享一列的数据表并将结果放入新的数据表中
【发布时间】:2012-09-22 16:06:10
【问题描述】:

我有以下数据表

table1

+-----------+------+------+
| catalogid | name | snum |
+-----------+------+------+
|       353 | xx   |    4 |
|       364 | yy   |    3 |
|       882 | zz   |    3 |
|       224 | mm   |   71 |
|       999 | kk   |  321 |
|        74 | kk   |    4 |
|        54 | ii   |    5 |
|        11 | u    |    6 |
|        23 | yy   |    6 |
+-----------+------+------+

table2

+-----------+----------+--------------+
| catalogid | numitems | ignoreditems |
+-----------+----------+--------------+
|       353 |        4 |            0 |
|       364 |       10 |            0 |
|       882 |        2 |            0 |
|       224 |        0 |            7 |
+-----------+----------+--------------+

使用 LINQ 我想加入它们并将结果复制到新的数据表中。他们都共享catalogid,结果应该只显示他们的catalogid存在于table2中的记录

结果

+-----------+------+------+-----------+---------------+
| catalogid | name | snum | numitems  | ignoreditems  |
+-----------+------+------+-----------+---------------+
|       353 | xx   |    4 |         4 |             0 |
|       364 | yy   |    3 |        10 |             0 |
|       882 | zz   |    3 |         2 |             0 |
|       224 | mm   |   71 |         0 |             7 |
+-----------+------+------+-----------+---------------+

这是我的尝试,但它不起作用:

 Dim query = From a In oresult.AsEnumerable
             Group Join b In products.AsEnumerable
             On a.Field(Of Integer)("catalogid") Equals b.Field(Of Integer)("catalogid")
             Into Group
 query.copytodatatable

CopyToDatatable 不工作,我不知道为什么

【问题讨论】:

    标签: vb.net linq datatable


    【解决方案1】:

    CopyToDataTable() 仅在您的查询返回 IEnumerable 时有效。在您的查询中,您将返回一个匿名类型。匿名类型不携带 CopyToDataTable() 的扩展方法。

    您可以使用下面列出的 ConvertToDataTable 扩展来创建表。您必须将其转换为 VB.NET(如果您用谷歌搜索,那里有转换器)。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using Common;
    
    namespace TestConsole
    {
        public class Linq_join_2_datatables_that_share_a_column_and_put_result_in_new_datatable
        {
            public class Table1
            {
                public int CatalogId { get; set; }
                public string Name { get; set; }
                public int SNum { get; set; }
            }
    
            public class Table2
            {
                public int CatalogId { get; set; }
                public int NumItems { get; set; }
                public int IgnoredItems { get; set; }
            }
    
            public static void Start()
            {
                DataTable table1 = new DataTable();
                table1.Columns.Add("catalogid", typeof(int));
                table1.Columns.Add("name", typeof(string));
                table1.Columns.Add("snum", typeof(int));
                DataRow row = table1.Rows.Add(353, "xx", 4);
    
                DataTable table2 = new DataTable();
                table2.Columns.Add("catalogid", typeof(int));
                table2.Columns.Add("numitems", typeof(int));
                table2.Columns.Add("ignoreditems", typeof(int));
                table2.Rows.Add(353, 4, 0);
    
                var query = (from t1 in table1.AsEnumerable()
                            join t2 in table2.AsEnumerable() on t1.Field<int>("catalogid") equals t2.Field<int>("catalogid")
                            select new
                            {
                                catalogid = t1.Field<int>("catalogid"),
                                name = t1.Field<string>("name"),
                                snum = t1.Field<int>("snum"),
                                numitems = t2.Field<int>("numitems"),
                                ignoreditems = t2.Field<int>("ignoreditems")
                            }).ToList();
    
                DataTable table3 = query.ConvertToDataTable();      
            }
        }    
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using System.ComponentModel;
    using System.Reflection;
    
    namespace Common
    {
        public static class DataTableExtensions
        {
            public static DataTable ConvertToDataTable<T>(this IList<T> data)
            {
                PropertyDescriptorCollection properties =
                    TypeDescriptor.GetProperties(typeof(T));
                DataTable table = new DataTable();
                foreach (PropertyDescriptor prop in properties)
                    table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
                foreach (T item in data)
                {
                    DataRow row = table.NewRow();
                    foreach (PropertyDescriptor prop in properties)
                        row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                    table.Rows.Add(row);
                }
                table.AcceptChanges();
                return table;
            }
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      CopyToDataRow 仅适用于 IEnumerables 或 DataRow。有关任意 IEnumerables 的 CopyToDataRow 的实现,请参见 this article at MSDN

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-15
        • 1970-01-01
        • 1970-01-01
        • 2011-09-30
        • 2014-05-16
        • 2023-04-07
        • 2012-02-13
        相关资源
        最近更新 更多