LINQ

Iridium implements a full LINQ provider in the IDataSet class. It has native support for .Where(), .OrderBy(), .ThenBy(), .Take(), .Skip(), .First()

LINQ queries will be translated to server-side queries whenever it makes sense (if the data provider supports it). Currently this is supported by any SQL data provider.

In addition, queries can be performed across relations and if possible the query will be translated to a server-side query with the appropriate joins.

.Where()

The following expressions are supported in a LINQ Where() expression:

  • A <operator> B
    • A and B should be numeric, booleans, dates or strings
    • Supported operators: ==,!=,<,>,<=,>=,+,-,/,*,&&,||
  • A.Length where A is a string
  • A.StartsWith(B) where A and B are strings
  • A.EndsWith(B) where A and B are strings
  • A.Contains(B) where A and B are strings
  • A.B where B is a many-to-one relation of A (this can be chained)
  • One-To-Many predicates
    • A.B.Any(condition) (condition is an optional condition lambda expression)
    • A.B.Count(condition) (condition is an optional condition lambda expression)
    • A.B.All(condition) (condition is an optional condition lambda expression)

Examples:

var orders = DB.Orders;

from o in orders where o.OrderDate < DateTime.Today select o
from o in orders where o.OrderItems.Count() > 1 select o
from o in orders where o.OrderItems.Any(item => item.ProductID == "A") select o
from o in orders where o.OrderItems.Any() select o
from o in orders where o.Customer.Name.StartsWith("A") select o

// or any combination
from o in orders 
      where o.Customer.Name == "John Doe" 
          && o.OrderDate < DateTime.Today 
          && o.OrderItems.Any() select o

If a query can't be translated to SQL, any part of the query that can't be translated will be evaluated in code at runtime. This will hurt performance but it will still give you the results you need.

For example, say you have a custom function to determine if a customer object should be included in a query, but you only want to select customers with a name starting with "A":

var customers = from customer in DB.Customers 
                where customer.Name.StartsWith("A") && CustomMethod(customer) 
                select customer;

It's obvious that the call to CustomMethod(customer) can't be translated to SQL so Iridium will do the following:

select * from Customer where Name like 'A%'

Then the results will filtered in code:

customers = customers.Where(c => CustomMethod(c))

Iridium will split the predicate and feed part of if to the database and part of it will be evaluated in code.

.OrderBy() and .ThenBy()

Any expression supported in a .Where() predicate is also supported for sorting.

.First() , .Take() and .Skip()

Most database drivers (including all SQL drivers) will execute a native query satisfying the criteria. In other words, Iridium will not get all the records and then take the first element. It will try to only retrieve the first record from the database.

Note that .Last() will still fetch all records.