LINQ Query
Executes a LINQ (Language Integrated Query) expression on a DataTable for advanced data manipulation, transformation, and analysis. This node provides powerful querying capabilities beyond simple filtering.
Common Properties
- Name - The custom name of the node.
- Color - The custom color of the node.
- Delay Before (sec) - Waits in seconds before executing the node.
- Delay After (sec) - Waits in seconds after executing node.
- Continue On Error - Automation will continue regardless of any error. The default value is false.
info
If the ContinueOnError property is true, no error is caught when the project is executed, even if a Catch node is used.
Input
- Table - DataTable to query
- LINQ Query - C# LINQ query expression to execute (edited in the code editor)
Output
- Result - Result of the LINQ query execution (type varies based on query)
LINQ Query Context
The table is available as dt in your LINQ query. You can access it using:
dt.AsEnumerable()- Convert to enumerable for LINQ operationsdt.Rows- Access rows directlydt.Columns- Access column information
Example Usage
Basic Selection and Projection
// Select specific columns
from user in dt.AsEnumerable()
select new {
Name = user.Field<string>("name"),
Email = user.Field<string>("email")
}
Filtering with Where Clause
// Filter rows where age is greater than 30
from user in dt.AsEnumerable()
where user.Field<int>("age") > 30
select new {
Name = user.Field<string>("name"),
Age = user.Field<int>("age")
}
Complex Filtering
// Multiple conditions
from user in dt.AsEnumerable()
where user.Field<string>("status") == "Active"
&& user.Field<int>("age") >= 18
&& user.Field<int>("age") <= 65
select user
Ordering Results
// Order by age descending
from user in dt.AsEnumerable()
orderby user.Field<int>("age") descending
select new {
Name = user.Field<string>("name"),
Age = user.Field<int>("age")
}
Grouping Data
// Group by city and count
from user in dt.AsEnumerable()
group user by user.Field<string>("city") into cityGroup
select new {
City = cityGroup.Key,
Count = cityGroup.Count()
}
Aggregations
// Calculate sum of salaries by department
from emp in dt.AsEnumerable()
group emp by emp.Field<string>("department") into deptGroup
select new {
Department = deptGroup.Key,
TotalSalary = deptGroup.Sum(e => e.Field<decimal>("salary")),
AvgSalary = deptGroup.Average(e => e.Field<decimal>("salary")),
Count = deptGroup.Count()
}
String Operations
// Filter by string pattern
from user in dt.AsEnumerable()
where user.Field<string>("email").Contains("@gmail.com")
select user
// String transformations
from user in dt.AsEnumerable()
select new {
Name = user.Field<string>("name").ToUpper(),
Email = user.Field<string>("email").ToLower(),
Domain = user.Field<string>("email").Split('@')[1]
}
Calculations and Transformations
// Calculate derived values
from product in dt.AsEnumerable()
select new {
ProductName = product.Field<string>("name"),
Price = product.Field<decimal>("price"),
Quantity = product.Field<int>("quantity"),
Total = product.Field<decimal>("price") * product.Field<int>("quantity"),
Discounted = product.Field<decimal>("price") * 0.9m
}
Top N Records
// Get top 10 highest salaries
(from emp in dt.AsEnumerable()
orderby emp.Field<decimal>("salary") descending
select new {
Name = emp.Field<string>("name"),
Salary = emp.Field<decimal>("salary")
}).Take(10)
Distinct Values
// Get distinct cities
(from user in dt.AsEnumerable()
select user.Field<string>("city")).Distinct()
Joining Data (Self-Join)
// Find users in the same city
from user1 in dt.AsEnumerable()
join user2 in dt.AsEnumerable()
on user1.Field<string>("city") equals user2.Field<string>("city")
where user1.Field<string>("name") != user2.Field<string>("name")
select new {
User1 = user1.Field<string>("name"),
User2 = user2.Field<string>("name"),
City = user1.Field<string>("city")
}
Conditional Logic
// Categorize by age
from user in dt.AsEnumerable()
select new {
Name = user.Field<string>("name"),
Age = user.Field<int>("age"),
Category = user.Field<int>("age") < 18 ? "Minor" :
user.Field<int>("age") < 65 ? "Adult" : "Senior"
}
Statistical Analysis
// Calculate statistics
new {
TotalRows = dt.AsEnumerable().Count(),
AvgAge = dt.AsEnumerable().Average(r => r.Field<int>("age")),
MinAge = dt.AsEnumerable().Min(r => r.Field<int>("age")),
MaxAge = dt.AsEnumerable().Max(r => r.Field<int>("age")),
TotalSalary = dt.AsEnumerable().Sum(r => r.Field<decimal>("salary"))
}
Method Syntax
// Using method syntax instead of query syntax
dt.AsEnumerable()
.Where(r => r.Field<int>("age") > 30)
.Select(r => new {
Name = r.Field<string>("name"),
Age = r.Field<int>("age")
})
.OrderBy(r => r.Age)
.ToList()
Field Types
When accessing fields, use the appropriate generic type:
Field<string>("columnName")- For textField<int>("columnName")- For integersField<decimal>("columnName")- For decimal numbersField<double>("columnName")- For floating-point numbersField<bool>("columnName")- For boolean valuesField<DateTime>("columnName")- For dates
Tips
- The LINQ query is written in C#, not JavaScript
- Use
dt.AsEnumerable()to convert the DataTable to a queryable collection - The query editor provides syntax highlighting for C#
- Results can be various types: collections, single values, anonymous objects
- Use
.ToList()at the end if you want to return a list - LINQ queries are evaluated lazily - add
.ToList()or.ToArray()to force evaluation - Complex queries may impact performance on large datasets
- Test your queries with sample data first
- The query must be a valid C# expression
Common Errors
Empty Table Error
Error: Table cannot be empty. Please provide a valid DataTable.
Solution: Ensure you're passing a valid DataTable object.
Query Syntax Error
Error: ErrQuery: [C# compilation error message]
Common causes and solutions:
// Wrong - missing Field type parameter
from user in dt.AsEnumerable()
where user.Field("age") > 30 // Error: missing type parameter
select user
// Correct
from user in dt.AsEnumerable()
where user.Field<int>("age") > 30
select user
// Wrong - incorrect column name (case-sensitive)
user.Field<string>("Name") // Error if column is "name"
// Correct - match exact column name
user.Field<string>("name")
// Wrong - missing semicolon or incorrect syntax
from user in dt.AsEnumerable()
select user.Field<string>("name") // Incomplete
// Correct - complete expression
from user in dt.AsEnumerable()
select new { Name = user.Field<string>("name") }
Type Mismatch Error
// Wrong - trying to get integer as string
var age = user.Field<string>("age"); // Error if age is int
// Correct - match the actual data type
var age = user.Field<int>("age");
Null Value Handling
// May throw error if column contains nulls
user.Field<int>("age")
// Safe null handling
user.Field<int?>("age") ?? 0 // Returns 0 if null
See Also
- Filter DataTable - Simple filtering
- Sort Table - Sort operations
- Lookup DataTable - Find specific values
- Get Column - Extract columns