Use of PXProjection: General Information

The PXProjection attribute is mainly used to perform complex Select operations by using a fluent BQL query. If you need to join a fluent BQL query that is also a complex joined select query, you should use the PXProjection attribute.

This attribute can also be used in situations where you need to display data from multiple tables on a form or a tab. To do this, you need to declare a DAC with the PXProjection attribute, which implements the projection of data from one table or multiple tables into a single DAC.

Learning Objectives

In this chapter, you will learn how to do the following:

  • Define the DAC for a new tab with the PXProjection attribute on an existing form
  • Define the data view for the new tab
  • Create a new tab item on an existing form

Applicable Scenarios

You use the PXProjection attribute in the following cases:

  • You want to join a fluent BQL query that on its own is a complex joined select query
  • You want to display data from multiple tables on a form or a tab

Workflow of PXProjection Attribute Configuration

The PXProjection attribute binds the DAC to an arbitrary dataset defined by the Select command. The framework does not bind this DAC to a database table (that is, it does not select data from the table with the same name as the DAC). Instead, you specify an arbitrary fluent BQL Select command that is executed to retrieve data for the DAC. The Select command can select data from one DAC or multiple DACs and can include any BQL clauses. Thus, you can think of PXProjection entities as the MYOB Acumatica Framework's version of SQL views. An example of the use of the PXProjection attribute is shown in the following code.

[PXProjection(typeof(
    SelectFrom<Supplier>.
    InnerJoin<SupplierProduct>.On<
     SupplierProduct.accountID.IsEqual<Supplier.accountID>>))]

    public class SupplierAccounts: PXBqlTable, IBqlTable 
    {}

In the projection DAC, you should explicitly map the projection fields to the database column retrieved by the Select command. To map a field, set the BqlField property of the attribute (such as PXDBString and PXDBDecimal) that binds the field to the database to the type that represents the column, as shown in the following code.

[PXDBString(15, IsUnicode = true, BqlField = typeof(Supplier.accountID))]
public virtual string AccountID { get; set; }

Alternatively, for the code example above, you can use the BqlTable property to map the field. The field binds by its name implicitly since the field has the same name in the Supplier table. Thus, the above code example can be rewritten as follows.

[PXDBString(15, IsUnicode = true, BqlTable = typeof(Supplier))]
public virtual string AccountID { get; set; }

If you do not want to list all DAC fields, you can inherit projection from one of the DACs in the Select command. In this case, you should not override fields from this DAC and add mapping by using BqlField. The following code shows an example.

[PXProjection(typeof(
    SelectFrom<Supplier>.
    InnerJoin<SupplierProduct>.On<
     SupplierProduct.accountID.IsEqual<Supplier.accountID>>))]

public class SupplierAccounts : Supplier //inherit from Supplier
{
    //You do not have to list fields from the Supplier DAC
    ...
}