如何在内存中查询一个 DataTable 来填充另一个数据表格

7
我将尝试更新一个微软报告。它会记录下有多少客户因何种原因被排除在转换过程之外。目前,该程序将所有删除的客户写回服务器,然后查询服务器以填充专用表格中的结果。
以下是当前的查询:
SELECT  DeletedClients.Reason, 
        COUNT(DeletedClients.Reason) AS Number, 
        CAST(CAST(COUNT(DeletedClients.Reason) AS float) 
            / CAST(t.Total AS float) 
            * 100 AS numeric(4, 1)) AS percentage
FROM DeletedClients CROSS JOIN
    (SELECT COUNT(*) AS Total
    FROM DeletedClients AS DeletedClients_1
    WHERE (ClinicID = @ClinicID)) AS t
WHERE (DeletedClients.ClinicID = @ClinicID) 
    AND (DeletedClients.TotalsIdent = @ident)
GROUP BY DeletedClients.Reason, t.Total
ORDER BY Number DESC

我想做的是不将DeletedClients写入服务器,因为它已经作为DataTable存在于我的程序中,并且仅会减慢报告的速度并向数据库中填充我们不需要保存的信息。
我的主要问题是:
如何查询数据表以创建一个新的内存数据表,其结果与使用上面的查询编写SQL服务器并重新读取有相同的结果?
或者
在Microsoft Reports中,如何对Tablix中的项目进行分组,以将=Fields!Reason.Value =Fields!Number.Value =Fields!percentage.Value转换为类似于上述查询返回结果的东西?

更多示例请参见 - dotnetperls.com/datatable-select Select("Size >= 230 AND Sex = 'm'"); Select("Date > #6/1/2001#"); - Steam
2个回答

11
你可以使用 DataTable.Select 查询 DataTable。
DataTable table = GetDataTableResults();
DataTable results = table.Select("SomeIntColumn > 0").CopyToDataTable();

或者对于更复杂的查询,您可以使用 LINQ 来查询 DataTable:

DataTable dt = GetDataTableResults();

var results = from row in dt.AsEnumerable()
              group row by new { SomeIDColumn = row.Field<int>("SomeIDColumn") } into rowgroup
              select new
              {
                  SomeID = rowgroup.Key.SomeIDColumn,
                  SomeTotal = rowgroup.Sum(r => r.Field<decimal>("SomeDecimalColumn"))
              };                    

DataTable queryResults = new DataTable();
foreach (var result in query)
    queryResults.Rows.Add(new object[] { result.SomeID, result.SomeTotal });

@JamesJohnson - 抱歉,您的方法对我无效。我无法导入必要的dll文件。您能帮我在这里找出问题吗 - http://stackoverflow.com/questions/20308852/copy-selected-data-from-datatable-to-another-datatable 。另外,如果系统中缺少必要的DLL,您的方法是否有效? - Trojan.ZBOT
@Trojan.ZBOT: 我认为只需要引用System.Data就可以使用这段代码,如果您无法导入该命名空间,则可能需要处理更大的问题。与System命名空间一样,.NET中基本上需要System.Data来进行数据驱动开发。 - James Johnson
@JamesJohnson - 我不确定是否是这样。我尝试了一个问题中给我的步骤,现在一切都正常工作。这是问题的链接 - http://stackoverflow.com/questions/20308852/copy-selected-data-from-datatable-to-another-datatable 我想知道我是否遗漏了什么。 - Trojan.ZBOT
@JamesJohnson - 我遇到了错误“System.Array”不包含“CopyToDataTable”的定义,也没有接受类型为“System.Array”的第一个参数的扩展方法“CopyToDataTable”(您是否缺少使用指令或程序集引用?) - Steam
有没有 .NET 3.5 之前的方法来做这件事?我无法导入所需的 .net dll - http://stackoverflow.com/questions/21005555/error-in-selecting-from-a-datatable-and-copying-the-datatable - Steam
显示剩余7条评论

3

我想到了两种查询数据表的方法。以下是使用这两种方法的示例。

using System;
using System.Data;

namespace WindowsFormsApplication1
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            var deletedClients = GetDataTable();

            // Using linq to create the new DataTable.
            var example1 = deletedClients.AsEnumerable()
                                         .Where(x => x.Field<int>("ClinicId") == 1)
                                         .CopyToDataTable();

            // Using the DefaultView RowFilter to create a new DataTable.
            deletedClients.DefaultView.RowFilter = "ClinicId = 1";
            var rowFilterExample = deletedClients.DefaultView.ToTable();
        }

        static DataTable GetDataTable()
        {
            var dataTable = new DataTable();
            // Assumes ClinicId is an int...
            dataTable.Columns.Add("ClinicId", typeof(int));
            dataTable.Columns.Add("Reason");
            dataTable.Columns.Add("Number", typeof(int));
            dataTable.Columns.Add("Percentage", typeof(float));

            for (int counter = 0; counter < 10; counter++)
            {
                dataTable.Rows.Add(counter, "Reason" + counter, counter, counter);
            }

            return dataTable;
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接