Blogs

Gary's Blog

XPO – Direct SQL Queries

     

In the comments to my previous blog post about executing stored procedures from XPO, you asked how you could execute a SQL query from within a persistent class, so in this post I thought I’d show you how it is done.

Taking an example from the previous post where Form1 contains a UnitOfWork, a XPDataView and a GridControl, and where XPDataView is a data source for a GridControl.

Firstly, you can simply execute the query, for example, the update discounts for orders:

public void UpdateDiscount(out int affectedRows) 
{
    affectedRows = unitOfWork1.ExecuteNonQuery("UPDATE [Northwind]" +
        ".[dbo].[Order Details] SET [Discount] = 0.15 WHERE "+
        "[UnitPrice] > 50");
}

Secondly, you can request and obtain a scalar value, for example, if you need to know the number of orders from a specific employee:

public int GetEmployeeOrdersCount(int employeeId)
{
    return (int)unitOfWork1.ExecuteScalar(string.Format(
        "SELECT COUNT(*) FROM [Northwind].[dbo].[Orders] " +
        "WHERE [EmployeeID] = {0}", employeeId));        
}

Thirdly, you can run a query that returns a result set:

using DevExpress.Xpo.DB;
//…
public SelectedData GetEmployeesSimpleData() 
{
    return unitOfWork1.ExecuteQuery("SELECT EmployeeID, (FirstName + ' ' " +
        "+ LastName) as Name, City, Country FROM " +
        "[Northwind].[dbo].[Employees]");
}

You will have to describe the class so that the data can be loaded into objects or a XPDataView:

[NonPersistent]
public class EmployeeSimple : XPLiteObject 
{
    [Key]
    public int EmployeeID;
    public string Name;
    public string City;
    public string Country;
    public EmployeeSimple(Session session) : base(session) { }
}

And since the order of fields in the class is the same as the order in the query, then the objects can be loaded as follows:

public ICollection<EmployeeSimple> GetEmployeesSimple()
{
    return unitOfWork1.GetObjectsFromQuery<EmployeeSimple>("SELECT " +
        "EmployeeID, (FirstName + ' ' + LastName) as Name, City, Country " +
        "FROM [Northwind].[dbo].[Employees]");
}

To load data into the XPDataView simply amend the  Form1_Load event as follows:

private void Form1_Load(object sender, EventArgs e)
{
    //Fill information about the properties of a class EmployeeSimple
    xpDataView1.FillProperties(unitOfWork1.GetClassInfo<EmployeeSimple>());

    //Load the data
    xpDataView1.LoadData(GetEmployeesSimpleData());
}

Executing that code will give you the following result:

Form with data result

If you don’t want to show all the fields, or if their order differs from the request, then you can provide additional information to obtain the correct fields in the correct order:

public SelectedData GetEmployeesDataForOrderExample()
{
    //Fields are mixed, and the field 'City' removed from the query
    return unitOfWork1.ExecuteQuery("SELECT (FirstName + ' ' + LastName) " +
    "as Name, Country, EmployeeID FROM [Northwind].[dbo].[Employees]");
}

//Array to specify the order of the fields in the query
static LoadDataMemberOrderItem[] employeesLoadOrder = new LoadDataMemberOrderItem[] 
{
    new LoadDataMemberOrderItem(2, "EmployeeID"),
    new LoadDataMemberOrderItem(0, "Name"),
    new LoadDataMemberOrderItem(1, "Country")

};

And once again modify the Form1_Load event:

private void Form1_Load(object sender, EventArgs e)
{
    XPClassInfo employeesClassInfo = unitOfWork1.GetClassInfo<EmployeeSimple>();

    //Using an array employeesLoadOrder
    xpDataView1.FillPropertiesOrdered(employeesClassInfo, employeesLoadOrder);
    xpDataView1.LoadOrderedData(employeesLoadOrder, GetEmployeesDataForOrderExample());
}

To get the following result:

Results form with reduced fields

I hope that answers some of your questions regarding SQL queries with 2010.2.

That’s all for this post, so until next time, happy XPOing! Smile

Published Oct 08 2010, 04:57 PM by Gary Short (DevExpress)
Filed under: ,
Technorati tags: v2010.2, XPO
Bookmark and Share

Comments

 

Nate Laff said:

Great to see some life in XPO again!!!

October 8, 2010 1:06 PM
 

Martin Hart said:

Gary:

I have always claimed that XPO was the best product DevExpress had produced (and they mave produced some really excellent products), but with the latest XPO extensions it has just got even better!

It is so good to see XPO back in the spotlight.

October 8, 2010 1:14 PM
 

Marc Greiner [DX-Squad] said:

Hi Gary ;

Does XPO tweak these SQL commands so that they run on the different DB systems without syntax errors ?

I noted that some of the SQL commands in your example make use of brackets. This would not work in Oracle (Oracle uses the non standard double quote for this).

October 8, 2010 1:55 PM
 

Haithem said:

Cool, that is really cool.

So now my big question which i cant hold it anymore : When is the release date????

Sorry, couldnt hold it much, i had to say it, reading all good features and components coming up on the next release leave me with no patience.

October 8, 2010 1:59 PM
 

Robert Fuchs said:

Can this be used in XAF?

Is it possible to use ExecuteQuery using ObjectSpace instead of UnitOfWork?

Is it possible to use ExecuteQuery within the same Transaction as ObjectSpace?

October 8, 2010 3:37 PM
 

Nate Laff said:

Oooh -- yeah, what Robert said. Would like that on ObjectSpace.

October 8, 2010 3:41 PM
 

Martin Praxmarer [DX-Squad] said:

Hi Robert / Nate,

why not ObjectSpace.Session.ExecuteQuery - do i miss something?

PS: Keep in mind the XAF gets decoupled from XPO, so it would not depend on ObjectSpace i think...?

October 8, 2010 6:03 PM
 

Hans Merkl said:

Is this for the next version?

October 8, 2010 8:47 PM
 

Alec Mironov said:

How about the FullText search feature wich is very specific to a database engine?

Will "Xpo - direct query" support this?

October 9, 2010 8:56 PM
 

Daniel Petrik said:

Just one question. When would be new version of XPO released?

October 11, 2010 2:50 AM
 

Slava D (DevExpress) said:

@All:

It is necessary to clarify that the methods described in the blog do not preprocess a request.

They are only a bridge to the ADO.NET provider.

October 11, 2010 8:00 AM
 

Marco Fuykschot said:

This is great, for me this removes the need to create dynamic views in de database in combination with XPView, now runtime and special optimized queries can be used.  

Do you need to use XPLiteObject, or can jou also use any of the other XPO base objects

October 21, 2010 4:58 PM
 

Dennis (DevExpress Support) said:

@Marco:

Normally, XPO class is required to simplify the process of working with XPDataView. However, you can use a POCO marked with the NonPersistentAttribute and registered in the XPDictionary.

October 23, 2010 6:14 PM
 

Hideaki Kusaka said:

I have one question.

Is Command Parameters Supported?

(ex: p.ProductID = :ProductID)

November 22, 2010 2:05 AM
 

Michael Tietz said:

In XPDataView there is no method FillPropertie, but PopulateProperties. The same is with FillPropertiesOrdered

December 3, 2010 11:04 AM
 

Michael Tietz said:

And there is no XPDataView.LoadData whith can take as parameter ICollection<T> ?

December 3, 2010 11:36 AM
 

Jorge Varas said:

Quick question.

Can this be used with xpAsyncServerModeSource data provider for the grid?

I can create a class on the fly, but I really need to query the database based on several joins, and I cannot use a view because I am going against SQL CE

January 12, 2011 5:12 PM
More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.