LINQ to XPO
- 4 minutes to read
XPO includes the XPQuery<T> class designed to build LINQ expressions and execute them against the underlying data store. XPQuery<T> can chain together multiple queries and supports deferred execution.
To run a query and load data, call the ToList()
or ToArray()
extension method, or use the foreach operator to enumerate XPQuery<T>.
You can create XPQuery<T> instances in the following ways:
- Create an instance from a session’s scope, via the session’s XPQueryExtensions.Query<T> extension method.
- Pass a session or Unit of Work to an XPQuery<T> constructor.
using System.Linq;
using DevExpress.Xpo;
XPQuery<Customer> customers = Session.DefaultSession.Query<Customer>();
// Equivalent definition.
// XPQuery<Customer> customers = new XPQuery<Customer>(Session.DefaultSession);
foreach (Customer cust in customers)
Console.WriteLine(string.Format("{0}", cust.ContactName));
In addition to calling the XPQueryExtensions.Query<T> extension method, you can call the XPQueryExtensions.QueryInTransaction<T> method to include all in-memory object changes to query results (as if Session.InTransactionMode is enabled). To create an InTransaction XPQuery<T> instance based on an existing XPQuery<T> instance, call its XPQuery<T>.InTransaction method.
Sample Expressions
using System.Linq;
using System.Linq.Expressions;
using DevExpress.Xpo;
XPQuery<Customer> customers = Session.DefaultSession.Query<Customer>();
XPQuery<Order> orders = Session.DefaultSession.Query<Order>();
XPQuery<Employee> employees = Session.DefaultSession.Query<Employee>();
// Simple Select with Where and OrderBy clauses
var list = from c in customers
where (c.Country == "Germany" && c.ContactTitle == "Sales Representative")
orderby c.ContactName
select c;
foreach (Customer cust in list)
Console.WriteLine(string.Format("{0}\t{1}\t{2}", cust.ContactName,
cust.Country, cust.ContactTitle));
// Select Top 5 objects
var list = (from o in orders
orderby o.ShippedDate descending
select o).Take(5);
foreach (Order order in list)
Console.WriteLine(string.Format("{0}\t{1}\t{2}", order.OrderID, order.ShippedDate,
order.Customer.CompanyName));
// Group Join customers with an aggregation on their Orders
var list = from c in customers
join o in orders on c equals o.Customer into oo
where oo.Count() >= 1
select new { c.CompanyName, OrderCount = oo.Count() };
foreach (var item in list)
Console.WriteLine(string.Format("{0}\t{1}", item.CompanyName, item.OrderCount));
// An example of aggregated functions (Count and Average)
var list = from o in orders
select o;
int count = list.Count();
Console.WriteLine(string.Format("Orders Row Count: {0}", count));
decimal avg = list.Average(x => x.Freight);
Console.WriteLine(string.Format("Orders Average Freight: {0:c2}", avg));
// Select with Group By
var list = from c in customers
group c by c.ContactTitle into cc
where cc.Count() >= 1
select new { Title = cc.Key, Count = cc.Count() };
foreach (var item in list)
Console.WriteLine(string.Format("{0}\t{1}", item.Title, item.Count));
// Any method
bool result = customers.Any(c => c.Country == "Spain");
Console.WriteLine(string.Format("Is there any customer from Spain? {0}", result ? "Yes" : "No"));
result = customers.Any(c => c.Country == "Monaco");
Console.WriteLine(string.Format("Is there any customer from Monaco? {0}", result ? "Yes" : "No"));
For more information on how to implement custom functions and criteria, and use them in LINQ to XPO expressions, see How to: Implement Custom Functions and Criteria in LINQ to XPO.