【问题标题】:Linq to datatable with unknown columnsLinq 到具有未知列的数据表
【发布时间】:2022-01-04 17:24:40
【问题描述】:

我有这样的 SQL 查询(一旦我完成这项工作就会被参数化):

using (FbCommand cmd = new FbCommand("SELECT MAGACINID, ROBAID, SUM(KOLICINA) AS GOD" + godina.ToString() + " FROM STAVKA WHERE VRDOK = 13 OR VRDOK = 15 GROUP BY MAGACINID, ROBAID ORDER BY ROBAID", con))
                        {
                            using (FbDataAdapter da = new FbDataAdapter(cmd))
                            {
                                DataTable tempDT = new DataTable();
                                if (dt.Rows.Count == 0)
                                {
                                    da.Fill(dt);
                                    continue;
                                }

                                da.Fill(tempDT);

                                var result = dt.AsEnumerable()
                                    .Join(tempDT.AsEnumerable(),
                                    x => new { field1 = x["MAGACINID"], field2 = x["ROBAID"] },
                                    y => new { field1 = y["MAGACINID"], field2 = y["ROBAID"] },
                                    (x, y) => new {
                                        x,
                                        addYear = y["GOD" + godina.ToString()]
                                    });

                                dt = LINQResultToDataTable(result);
                            }
                        }

这里是LINQResultToDataTable() 方法


        private DataTable LINQResultToDataTable<T>(IEnumerable<T> Linqlist)
        {
            DataTable dt = new DataTable();
            PropertyInfo[] allColumns = null;

            if (Linqlist == null) return dt;

            foreach (T Record in Linqlist)
            {
                if (allColumns == null)
                {
                    allColumns = ((Type)Record.GetType()).GetProperties();

                    // Record at position 0 is whole object and needs to be broke into pieces
                    // Record at position 1 is new column

                    foreach (PropertyInfo GetProperty in allColumns)
                    {
                        Type colType = GetProperty.PropertyType;

                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
                               == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }

                        dt.Columns.Add(new DataColumn(GetProperty.Name, colType));
                    }
                }

                DataRow dr = dt.NewRow();

                foreach (PropertyInfo pinfo in allColumns)
                {
                    dr[pinfo.Name] = pinfo.GetValue(Record, null) == null ? DBNull.Value : pinfo.GetValue
                           (Record, null);
                }

                dt.Rows.Add(dr);
            }
            return dt;
        }

第一个数据表填充没问题,它用这些列填充它:

MagacinID
RobaID
God2021

现在,当我尝试使用 linq 加入新表时,我应该只添加 God2020 作为新列。 问题是,当我创建 linq 的输出时,我无法告诉它将 x 对象分成列,但我需要将其完整,因此 linq 结果如下所示:

x (this one have ItemArray with all columns)
God2020

新的数据表看起来一样。

我尝试做的是在LINQResultToDataTable 方法中获取Result0th 元素并将其分成列,添加到数据表,添加新元素(第一个元素)并填充它(请参阅该方法中的注释)但我被卡住了,不知道该怎么做。谁有解决办法?

编辑:我说不清楚,所以这里有更多解释。

我有 foreach 循环,它循环通过 5 databases 并且在 foreach 循环内是这段代码。

第一个数据库返回这些列

MagacinID
RobaID
God2021

第二

MagacinID
RobaID
God2020

第三

MagacinID
RobaID
God2019

第四

MagacinID
RobaID
God2018

第五

MagacinID
RobaID
God2017

我希望将所有这些合并到一个数据表中的列MagacinID AND RobaID 上,如下所示:

MagacinID
RobaID
God2021
God2020
God2019
God2018
God2017

【问题讨论】:

  • 我认为您的问题不完整。在与您的问题无关的想法中,我个人不会为此使用 linQ,我将尝试在 DB 层解决此类问题。
  • @LeandroBardelli 问题是我正在更改连接字符串(不同的数据库),所以我不能在 DB 层上这样做
  • 你可以做数据库链接。但我认为你必须编辑你的问题,因为以“像这样:”结束,仅此而已
  • @LeandroBardelli 抱歉,已更正.. 只是说明而已。
  • 我很困惑 - 您正在从查询中填充数据表,然后将其投影到匿名类型,只是想将它放回作为数据表?

标签: c# linq


【解决方案1】:

Merge 是指使用 DataTable 合并,它基本上对数据表中声明的 PK 字段执行类似完全外部联接的操作,然后将合并到的表作为联接的结果;

        var d1 = new DataTable();
        d1.Columns.Add("SomeId");
        d1.Columns.Add("Col1");

        d1.Rows.Add("ID1", "Col1Val1");
        d1.Rows.Add("ID2", "Col1Val2");
        d1.PrimaryKey = new[] { d1.Columns["SomeId"] };



        var d2 = new DataTable();
        d2.Columns.Add("SomeId");
        d2.Columns.Add("Col2");

        d2.Rows.Add("ID1", "Col2Val1");
        d2.Rows.Add("ID3", "Col2Val2");
        d2.PrimaryKey = new[] { d2.Columns["SomeId"] };



        var d3 = new DataTable();
        d3.Columns.Add("SomeId");
        d3.Columns.Add("Col3");

        d3.Rows.Add("ID2", "Col3Val1");
        d3.Rows.Add("ID3", "Col3Val2");
        d3.PrimaryKey = new[] { d3.Columns["SomeId"] };


        d1.Merge(d2, false, MissingSchemaAction.Add);
        d1.Merge(d3, false, MissingSchemaAction.Add);

以上代码的结果如下:

d1 从两列开始,然后在第一次合并期间添加第三列 (Col2),并将 d2 的 Col2 中的值放入 d1 的 Col2,与 PK 列 (SomeId) 匹配。

然后在第二次合并期间,将第四列添加到 d1 (Col3),并将 d3 中 Col3 之外的值复制到 d1。

您会注意到我故意让d2d1 具有不同的PK 值,因此不仅添加了新列,还添加了新行

第二次合并操作没有添加新行(d1 已经有 ID1、ID2 和 ID3)

【讨论】:

  • 在我的问题中我没有PKUNIQUE(MAGACINID, ROBAID)
  • 哦,我发现了如何添加多个主键...我想它会解决我的问题
  • d2.PrimaryKey = new[] { d2.Columns["SomeId"], d2.Columns["SomeOtherId"] };
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 2013-02-05
相关资源
最近更新 更多