Study guide

5.2 Advanced DataTable Querying with LINQ

UiPath Automation Developer Professional UiPath-ADPv1

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Exam Overview & Blueprint Map

1.1 About the UiPath-ADPv1 Exam: Format, Fees & Policies 1.2 The Exam Topics Mapped to This Guide & a Study Plan

2 Chapter 2: REFramework Architecture & State Dynamics

2.1 State Machine Architecture & The Four Core States 2.2 Configuration Management: Settings, Constants, and Assets 2.3 Transaction Types & The Dispatcher vs. Performer Architecture 2.4 Adapting REFramework: Tabular Data, Collections & Linear Processes

3 Chapter 3: REFramework Exception Handling & Recovery

3.1 BusinessRuleException vs. System.Exception Handling Patterns 3.2 Retry Mechanisms: Queue Retries vs. REFramework MaxRetryNumber 3.3 Consecutive System Exceptions & Graceful Process Termination

4 Chapter 4: State Machines, Custom Log Fields & REFramework Testing

4.1 Building State Machine Projects in Studio 4.2 Logging Levels, Robot Logs & Custom Log Fields in REFramework 4.3 Testing a REFramework Project With and Without Orchestrator Queues

5 Chapter 5: LINQ Queries & DataTable Operations

5.1 LINQ Essentials for Collections & Filtering 5.2 Advanced DataTable Querying with LINQ 5.3 In-Memory DataTable Transformations & Column Operations

6 Chapter 6: Regex, DateTime, JSON & Invoke Activities

6.1 Regular Expressions & Text Parsing for Automation 6.2 DateTime Formatting, Timezone Conversions & TimeSpan Calculations 6.3 JSON Parsing, JSONPath & Serialization with Newtonsoft.Json 6.4 Invoke Method & Invoke Code Activities 6.5 Data Referencing in Invokes: DataTable, List & Dictionary Arguments

7 Chapter 7: Modern UI Automation & Unified Targeting

7.1 Modern Design Experience & The Unified Target Concept 7.2 Anchors, Relative Elements & UI Automation Activities 7.3 Dynamic Selectors, Variables & Wildcards in Selectors

8 Chapter 8: Object Repository, Computer Vision & Remote Runtime

8.1 Object Repository & UI Descriptor Libraries 8.2 AI Computer Vision for Unattended & Remote Interfaces 8.3 Automation in Virtual Environments & UiPath Remote Runtime

9 Chapter 9: Advanced UI Automation: Browser Modes, Agentic UI & macOS

9.1 Browser Automation with the WebDriver Protocol 9.2 Agentic UI Automation: ScreenPlay, Semantic Activities & Healing Agent 9.3 macOS Automation: Native Apps, Office Apps & AppleScript

10 Chapter 10: Advanced Control Flow & Exception Architecture

10.1 Flowcharts, Sequences & Parallel Control Flow Patterns 10.2 Global Exception Handler Architecture & ErrorAction Directives 10.3 TryCatch, Retry Scope & Custom Exception Architectures

11 Chapter 11: Orchestrator Queues & Transaction Management

11.1 Queue Architecture, SpecificContent & Transaction Lifecycles 11.2 Queue Items SLA, Postpone, Deadlines & Priority Scheduling 11.3 Bulk Operations, Transaction Status Updates & Queue Triggers

12 Chapter 12: Orchestrator Tenant & Folder Entities

12.1 Asset Types, Per-Robot Assets & External Credential Stores 12.2 Modern Folder Hierarchy, User/Robot Assignment & Permissions 12.3 Storage Buckets, Webhooks & Environment Promotion 12.4 Orchestrator Tags: Labels, Properties & Governance

13 Chapter 13: Unattended Execution, API Triggers & Cloud Robots

13.1 Unattended Job Execution: Folders, Priorities, Background vs. Foreground & Runtimes 13.2 API Triggers: Starting Jobs from External Systems over HTTP 13.3 Serverless and Cloud VM Robots: Cloud-Hosted Execution Options

14 Chapter 14: Monitoring, Recording & Solutions Management

14.1 Orchestrator Monitoring, Trigger Alerts & Job Health 14.2 Job and Transaction Recording: Troubleshooting Faulted Unattended Jobs 14.3 Solutions Management: Packaging and Deploying Automations with Their Resources

15 Chapter 15: Debugging, Remote Debugging & Profiling

15.1 Studio Debugging Tools: Breakpoints, Panels & Execution Control 15.2 Remote Debugging: Remote Machine and Unattended Robot Connections 15.3 Profile Execution: Finding Performance Bottlenecks in Studio

16 Chapter 16: RPA Testing & Test Suite

16.1 UiPath Test Suite Overview, Test Cases & Given-When-Then Structure 16.2 Data-Driven Testing, Test Verification Activities & Mock Activities 16.3 CI/CD Pipelines with uipcli & Test Manager Traceability

17 Chapter 17: Long-Running Workflows, Action Center & Apps

17.1 Long-Running Workflows: Persistence, Suspend and Resume 17.2 Action Center & Human-in-the-Loop Orchestration 17.3 UiPath Apps: Action Apps, Automations & Integration Service

18 Chapter 18: Trigger-Based Attended Automation & Callouts

18.1 Trigger-Based Attended Automation: Forms, Triggers & Global Variables 18.2 Running Local Triggers & the Event Inspection Tool 18.3 Callouts & Forms for Attended Guidance

19 Chapter 19: UiPath Assistant & Robot Sessions

19.1 UiPath Assistant: Automations, Reminders, Widgets & Configuration 19.2 Robot Session (Picture in Picture): Child Session vs. Virtual Desktop

20 Chapter 20: Autopilot for Developers & Autopilot for Everyone

20.1 Autopilot for Developers: AI Assistance in Studio and Studio Web 20.2 Autopilot for Everyone: Chat, Automations & Clipboard AI

21 Chapter 21: API Automation & Integration Service

21.1 Integration Service: Connectors, Connections & Connector Activities 21.2 API Workflows in Studio Web 21.3 HTTP Requests: Web APIs, the Orchestrator API & Connector Requests 21.4 Connector Builder: Custom Integration Service Connectors 21.5 Integration Service Event Triggers: Connected and Disconnected 21.6 GenAI Activities: Generative AI Inside Workflows

22 Chapter 22: Data Service, Context Grounding & Coded Workflows

22.1 Data Fabric (Data Service) Entities: Modeling Business Data 22.2 Data Fabric Activities and the Platform Connector 22.3 Context Grounding: Retrieval-Augmented Generation with Company Data 22.4 Coded Automations: Structure, Arguments & Invoking Workflows 22.5 Coded Automation Services: Orchestrator, UI Automation, Microsoft 365 & Custom Services

23 Chapter 23: Integrated Scenario Practice

23.1 Integrated Scenario Practice: Designing an End-to-End Solution

5.2 Advanced DataTable Querying with LINQ

Key Takeaways Explain This Topic AI

System.Data.DataTable does not natively implement IEnumerable(Of DataRow); calling the .AsEnumerable() extension method from System.Data.DataSetExtensions is mandatory to enable LINQ operators.

The strongly typed r.Field(Of T)("ColumnName") method safely handles database nulls (DBNull.Value) by returning Nothing or nullable primitive types, preventing runtime InvalidCastException errors.

Executing .CopyToDataTable() on an empty IEnumerable(Of DataRow) throws a fatal System.InvalidOperationException; robust automations must guard the call using .Any() or fallback to dt.Clone().

LINQ GroupBy enables multi-column composite key grouping and aggregate calculations (Sum, Average, Count, Min, Max) across DataRows within a single Assign expression.

LINQ inner and left outer joins provide superior throughput, composite key matching, and expression flexibility compared to the visual Join Data Table activity.

Last updated: September 2026

5.2 Advanced DataTable Querying with LINQ

The System.Data.DataTable object is the foundational data structure for tabular automation in UiPath Studio. Whether reading Excel spreadsheets, scraping web tables, extracting structured PDF data, or querying SQL databases, developers routinely manipulate DataTables. However, performing multi-condition filtering, aggregation, and relational joins through procedural activities like Filter Data Table , Join Data Table , or nested For Each Row in Data Table quickly leads to brittle and sluggish automations.

Applying LINQ to DataTable objects provides declarative, high-speed, in-memory querying. This section details the mechanics of converting DataTables to enumerable sequences, strongly typed field extraction, defensive materialization patterns, grouping aggregations, and relational join patterns.

1. Bridging ADO.NET and LINQ via .AsEnumerable()

The DataTable class originated in early versions of the .NET Framework, prior to the introduction of generic collections ( IEnumerable(Of T) ) and LINQ in .NET 3.5. Consequently, the DataTable.Rows property returns a DataRowCollection , which implements only the non-generic IEnumerable interface.

To bridge this legacy ADO.NET structure with modern generic LINQ operators, Microsoft introduced the System.Data.DataSetExtensions library. Calling the .AsEnumerable() extension method on a DataTable exposes the table's rows as an EnumerableRowCollection(Of DataRow) , enabling full access to LINQ operators such as .Where() , .Select() , and .GroupBy() . ' Visual Basic .NET: Bridging DataTable to generic LINQ sequence

Dim rowSequence As EnumerableRowCollection(Of DataRow) = dt_Transactions.AsEnumerable() // C#: Bridging DataTable to generic LINQ sequence

EnumerableRowCollection<DataRow> rowSequence = dt_Transactions.AsEnumerable();

Note

Ensure that System.Data.DataSetExtensions is imported in the Imports panel in UiPath Studio. In modern Windows (.NET 6/8) UiPath projects, this namespace is imported by default, but legacy Windows - Legacy projects may require explicit verification.

2. Strongly Typed Column Access: Field(Of T) vs. Untyped Indexing

When querying a DataRow , developers can access column values using untyped indexing (e.g., row("Amount") ) or the strongly typed row.Field(Of T)("ColumnName") extension method. Understanding the difference is crucial for preventing runtime crashes:

The Untyped Indexing Pitfall

Untyped row access ( row("Amount") ) returns a System.Object . If the cell in the database or Excel sheet contains a null value, ADO.NET represents it as System.DBNull.Value . Attempting to convert DBNull.Value using explicit casting (e.g., CDbl(row("Amount")) or Convert.ToDouble(row("Amount")) ) throws an unhandled System.InvalidCastException: Specified cast is not valid .

The Strongly Typed Field(Of T) Advantage

The r.Field(Of T)() method provides compile-time type safety and native handling of DBNull.Value :

If the column holds a value type (such as Double , Int32 , or DateTime ) that might be null in the source data, specifying a Nullable type ( Nullable(Of Double) or Double? ) causes Field(Of T) to safely return Nothing ( null ) instead of throwing an exception.

If the column is a reference type ( String ), Field(Of String) safely returns Nothing for null cells. ' VB.NET: Multi-column filtering with typed field access and null safety

  • Dim filteredDT As DataTable = dt_Orders.AsEnumerable().Where(Function(r) _
  • r.Field(Of String)("Country") = "USA" AndAlso _
  • r.Field(Of Double?)("TaxAmount").HasValue AndAlso _
  • r.Field(Of Double)("TotalAmount") >= 1000.0 _
  • ).CopyToDataTable() // C#: Multi-column filtering with typed field access and null safety
  • DataTable filteredDT = dt_Orders.AsEnumerable().Where(r =>
  • r.Field<string>("Country") == "USA" &&
  • r.Field<double?>("TaxAmount").HasValue &&
  • r.Field<double>("TotalAmount") >= 1000.0
  • ).CopyToDataTable();
  • 3. The .CopyToDataTable() Hazard and Defensive Patterns

The .CopyToDataTable() extension method inspects an IEnumerable(Of DataRow) sequence and constructs a new DataTable containing identical schema metadata and row contents. However, it contains a critical architectural hazard:

Caution

If .CopyToDataTable() is invoked on an IEnumerable(Of DataRow) that contains zero rows , it immediately throws System.InvalidOperationException: The source contains no DataRows.

This exception occurs because .CopyToDataTable() determines the schema of the resulting table by reading the Table property of the first DataRow in the sequence. If the filter matches zero rows, schema discovery cannot occur, causing a fatal error.

Defensive Pattern 1: The Ternary Guard with .Clone()

A DataTable.Clone() call produces an empty table possessing the exact schema, column data types, constraints, and expressions of the source table, with zero rows. By pairing .Any() with an If() ternary expression, developers guarantee that empty results safely return an empty cloned table without throwing an exception: ' VB.NET: Ternary guard preventing InvalidOperationException

  • dt_HighValueOrders = If(dt_Orders.AsEnumerable().Any(Function(r) r.Field(Of Double)("Amount") > 10000.0), _
  • dt_Orders.AsEnumerable().Where(Function(r) r.Field(Of Double)("Amount") > 10000.0).CopyToDataTable(), _
  • dt_Orders.Clone())
  • Defensive Pattern 2: Intermediate DataRow Array Buffering

Evaluating the filter predicate twice (once in .Any() and once in .Where() ) can be inefficient on large datasets. Buffering the filtered rows into a DataRow() array avoids redundant evaluation: ' Step 1 (Assign activity): Buffer filtered rows into DataRow array

matchingRows = dt_Orders.AsEnumerable().Where(Function(r) r.Field(Of Double)("Amount") > 10000.0).ToArray()

' Step 2 (Assign activity): Materialize to DataTable with count check

dt_HighValueOrders = If(matchingRows.Length > 0, matchingRows.CopyToDataTable(), dt_Orders.Clone()) // C#: Intermediate array buffering

  • DataRow[] matchingRows = dt_Orders.AsEnumerable().Where(r => r.Field<double>("Amount") > 10000.0).ToArray();
  • DataTable dt_HighValueOrders = matchingRows.Length > 0 ? matchingRows.CopyToDataTable() : dt_Orders.Clone();
  • 4. Grouping Rows and Computing Aggregations ( GroupBy )

In business automations, generating summary reports—such as calculating total revenue per sales department or counting active orders per client—is a ubiquitous requirement. LINQ's .GroupBy() operator groups matching DataRow elements by a specified key.

Single-Column Grouping and Aggregation ' VB.NET: Group sales by Department and calculate total revenue and transaction count

' Assuming dt_Summary has columns: Department (String), TotalRevenue (Double), TxCount (Int32)

  • For Each grp In dt_Sales.AsEnumerable().GroupBy(Function(r) r.Field(Of String)("Department"))
  • Dim deptName As String = grp.Key
  • Dim totalRev As Double = grp.Sum(Function(r) r.Field(Of Double)("Revenue"))
  • Dim count As Int32 = grp.Count()
  • dt_Summary.Rows.Add(deptName, totalRev, count)
  • Next
  • Multi-Column Composite Key Grouping

To group by multiple columns simultaneously (e.g., grouping by both Region and Year ), create an anonymous type containing key properties: ' VB.NET: Group by composite key (Region and Year)

  • Dim compositeGroups = dt_Sales.AsEnumerable().GroupBy(Function(r) New With {
  • Key .Region = r.Field(Of String)("Region"),
  • Key .Year = r.Field(Of Int32)("FiscalYear")
  • })
  • For Each grp In compositeGroups
  • Dim regionName As String = grp.Key.Region
  • Dim fiscalYear As Int32 = grp.Key.Year
  • Dim avgDealSize As Double = grp.Average(Function(r) r.Field(Of Double)("DealSize"))
  • Dim maxDealSize As Double = grp.Max(Function(r) r.Field(Of Double)("DealSize"))
  • dt_Report.Rows.Add(regionName, fiscalYear, avgDealSize, maxDealSize)
  • Next
  • Supported Aggregation Functions
  • Aggregation Operator Purpose Example LINQ Syntax
  • .Sum() Computes the arithmetic total of numeric values grp.Sum(Function(r) r.Field(Of Decimal)("Amount"))
  • .Average() Computes the arithmetic mean of numeric values grp.Average(Function(r) r.Field(Of Double)("Score"))

.Count() Returns the total number of rows in the group grp.Count() or grp.Count(Function(r) r.Field(Of Boolean)("IsValid"))

.Max() Retrieves the maximum value (numeric, string, or date) grp.Max(Function(r) r.Field(Of DateTime)("CreatedDate"))

  • .Min() Retrieves the minimum value (numeric, string, or date) grp.Min(Function(r) r.Field(Of Decimal)("Cost"))
  • 5. Relational DataTable Joins: LINQ vs. Join Data Table Activity

UiPath provides the visual Join Data Table activity to merge two DataTables based on matching column values. While suitable for simple equijoins, it suffers from notable architectural limitations:

Its wizard compares column pairs with fixed operators; you can add several rules, but you cannot join on calculated keys or expressions.

It requires configuring output column retention wizards that can mangle duplicate column names.

It exhibits poor execution performance when joining tables with tens of thousands of rows.

LINQ joins execute directly in CLR memory, supporting multi-column keys and complex selection projections.

LINQ Inner Join

An inner join returns only rows where matching keys exist in both tables: ' VB.NET: LINQ Inner Join between dt_Orders and dt_Customers on CustomerID

  • ' Assumes dt_JoinedResult is initialized with desired target columns
  • dt_JoinedResult = (From o In dt_Orders.AsEnumerable()
  • Join c In dt_Customers.AsEnumerable()
  • On o.Field(Of Int32)("CustomerID") Equals c.Field(Of Int32)("CustomerID")
  • Select dt_JoinedResult.LoadDataRow(New Object() {
  • o.Field(Of Int32)("OrderID"),
  • c.Field(Of String)("CustomerName"),
  • c.Field(Of String)("Email"),
  • o.Field(Of Double)("OrderAmount")
  • }, False)).CopyToDataTable()
  • LINQ Left Outer Join ( GroupJoin + DefaultIfEmpty )

A left outer join retains all rows from the left table ( dt_Orders ), populating columns from the right table ( dt_Customers ) when a match exists, and providing default or fallback values when no match is found: ' VB.NET: LINQ Left Outer Join preserving all orders

  • dt_JoinedResult = (From o In dt_Orders.AsEnumerable()
  • GroupJoin c In dt_Customers.AsEnumerable()
  • On o.Field(Of Int32)("CustomerID") Equals c.Field(Of Int32)("CustomerID") Into custGroup = Group
  • From subCust In custGroup.DefaultIfEmpty()
  • Select dt_JoinedResult.LoadDataRow(New Object() {
  • o.Field(Of Int32)("OrderID"),
  • If(subCust Is Nothing, "UNKNOWN CLIENT", subCust.Field(Of String)("CustomerName")),
  • If(subCust Is Nothing, "N/A", subCust.Field(Of String)("Email")),
  • o.Field(Of Double)("OrderAmount")
  • }, False)).CopyToDataTable()
  • Comparison: Join Data Table Activity vs. LINQ Join
  • Feature UiPath Join Data Table Activity LINQ Relational Join ( Assign )
  • Setup Style Graphical modal wizard Declarative C# / VB.NET expression

Composite Keys Supported by adding several column-pair rules Native; join on New With { Key .A = ..., Key .B = ... }

Custom Null Handling Hardcoded null propagation; columns contain DBNull Granular fallback expressions via If(subCust Is Nothing, ...)

Throughput (100k rows) Moderate to slow (high activity tracking overhead) High (optimized hash-join algorithm inside CLR)

Transformation on Join Impossible without subsequent looping Transform fields during projection (e.g., .ToUpper() , calculations)

Loading diagram... Defensive Left Outer Join and Materialization Workflow