【问题标题】:How to apply a SQL statement on one or more DataTable's?如何在一个或多个 DataTable 上应用 SQL 语句?
【发布时间】:2019-03-25 15:40:42
【问题描述】:

问题

请帮助我编写一个可以接受的 C# 或 vb.net 例程

  • DataTable
  • 作为string 的SQL 查询

并创建

  • DataTable 将查询结果应用于输入 DataTable

据我所知,在 .net 中运行 SQL 的工具是 linq,但这并没有让我找到解决方案。

在 VB.net 中:如何实现这样的功能

Public Function SelectFromDataTable(Sql As String, T1 As DataTable) As DataTable
        // Apply Sql to T1
    End Function

(甚至更好,像这样)

Public Function SelectFromDataTable(Sql As String, T1 As DataTable, Optional T2 As DataTable) As DataTable
        // Apply Sql to T1 and T2
    End Function

到目前为止我尝试了什么

出于某种原因,我认为 linq 可能是解决方案,但这不是必需的。

试用 1

如果我寻找 linq 和 DataTable 的组合,我会得到你在 .net 代码中内联编写类似 sql 的代码的典型语法,如 on。 Queries in LINQ to DataSet

我希望在我的例程之外定义查询,所以您也可以从 SQL 字符串创建此类查询吗?

试用 2

在寻找 linq 和 SQL 的组合时,我得到了使用 SqlDataAdapter 的示例,但它们需要一个 SqlConnection,它显然必须指向一个数据库,如 How to receive a SQL-Statement as a DataTable

但是,对我来说,不仅目标,源也应该是DataTable,所以你能不能也为DataTables创建一个SqlConnection

上下文

如果你好奇我的问题来自哪里:

BluePrism 是一款图形机器人流程自动化 (RPA) 工具。它有一个名为 collection 的容器对象,它位于 .net DataTable 的底层,并且很少支持操作这些对象。

幸运的是,可以在 .net 中创建所谓的“业务对象”并实现接收和返回变量的“操作”。 (这是为了操作其他应用程序,但也可以用于操作数据。)

我们已经有了这样一个对象,我们称之为Collection Manipulation。其中一项操作Filter Collection 实现为

Dim NewRow As DataRow

Collection_Out = Collection_In.Clone

For Each parentRow As DataRow In Collection_In.Select(Select_Condition)
    NewRow = Collection_Out.NewRow
    For Each c As DataColumn In NewRow.Table.Columns
        NewRow(c.ColumnName) = parentRow(c.ColumnName)
    Next
    Collection_Out.Rows.Add(NewRow)
Next

NewRow = Nothing
Collection_In = Nothing

我想实现一个通用操作,对我的集合运行查询,例如

select category, sum(unit_price * units) as total_price 
from invoice 
group by category;

select article, order.units - delivery.units as units_missing 
from order, delivery 
where order.article = delivery.article;

【问题讨论】:

  • 你可以使用DataTable.Slect方法过滤掉带有字符串的行吗?您需要什么类型的查询?
  • 谢谢,我为您编辑了问题的上下文部分。
  • linq 是否允许“作为数据库表”存储/查看 DataTables 并查询它们,即使您没有真正的数据库?
  • 您可以直接在数据源上使用 OLEDB 方法或将您的集合粘贴到 excel 中运行 SQL 查询吗?
  • 我的数据源是DataTables。我可以在没有数据库的情况下使用 OLEDB 吗?

标签: sql .net linq datatable blueprism


【解决方案1】:

如果我对您的问题的理解正确,您需要一种 SQL 语法,例如用于数据表的多用途选择。

根据此处找到的信息:https://www.hanselman.com/blog/TheWeeklySourceCode48DynamicQueryableMakesCustomLINQExpressionsEasier.aspx,我进一步编写了以下示例。您可以根据需要进行扩展。

TL;DR 添加 System.Linq.Dynamic NuGet 包,以便您可以将字符串用于 where 子句等。

顺便说一句:编写一个查询字符串解析器,例如解析“select category, sum(unit_price * units) as total_price from invoice group by category;”完全有可能,但是恕我直言,您将花费大量时间而收效甚微。

using System.Data;
using System.Linq;
using System.Linq.Dynamic;

namespace Foo {
    public class Bar {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="from"></param>
        /// <param name="where"></param>
        /// <param name="skipRows"></param>
        /// <param name="takeRows"></param>
        /// <param name="orderBy">Needed for range selections (skipRows, takeRows) </param>
        /// <returns></returns>
        public DataTable GeneralPurposeSelect(DataTable from, string where = null, int? skipRows = null, int? takeRows = null, string orderBy = "Id") {
            var fromQryAble = from.AsEnumerable().AsQueryable();

            IQueryable<DataRow> toQryAble = null;
            if (!string.IsNullOrEmpty(where)) {
                toQryAble = fromQryAble.Where(where);
            }
            if (takeRows != null) {
                if (skipRows == null) {
                    skipRows = 0;
                }
            }
            if (skipRows != 0) {
                if (takeRows == null) {
                    takeRows = int.MaxValue;
                }
            }
            if (takeRows != null) {
                if (skipRows == null) {
                    skipRows = 0;
                }
                toQryAble = toQryAble == null ?
                    fromQryAble.OrderBy(orderBy).Skip(skipRows.Value).Take(takeRows.Value) :
                    toQryAble.OrderBy(orderBy).Skip(skipRows.Value).Take(takeRows.Value);
            }

            return toQryAble == null ? from : toQryAble.CopyToDataTable();
        }
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2018-10-23
  • 2014-06-23
相关资源
最近更新 更多