To Define a Unique Key
You can define the unique key of a data access class (DAC) by using the PrimaryKeyOf<Table>.By<keyFields> class. With this class, you can define simple keys (with one key field) and compound keys (with up to eight key fields) and select records by using these keys, as described in this topic.
The primary key differs from unique keys only by two things: Its name is
PK
, and its set of fields consists of only DAC key properties
(DAC properties marked with IsKey = true
). The DAC should not have
any unique key declarations without a primary key declaration.
To Define a Unique Key
- In the DAC, declare a
PrimaryKeyOf<Table>.By<keyFields>
descendant with the
public
Find method, which calls theprotected
FindBy method, as shown in the following code.using PX.Data.ReferentialIntegrity.Attributes; public partial class INSite : PXBqlTable, IBqlTable { public class UK : PrimaryKeyOf<INSite>.By<siteCD> { public static INSite Find(PXGraph graph, string siteCD) => FindBy(graph, siteCD); } public abstract class siteCD : PX.Data.BQL.BqlString.Field<siteCD> { } }
- Use the primary key to select a record, as shown in the following
code.
INSite item = INSite.UK.Find(this, value);
The unique key declaration is similar to a primary key declaration: The only difference is that it specifies DAC fields that are different from the fields used in a DAC primary key. The unique key declaration uses the same MYOB Acumatica Framework classes, and all examples for primary keys can be used to declare unique keys.
Examples of Usage
Suppose that a DAC has two different keys, and each of them can uniquely identify a
record in the database. To declare them both, you need to declare one primary key
named PK
and one unique key named UK
. An example
is shown in the following code.
public partial class INSite : PXBqlTable, IBqlTable
{
public class PK : PrimaryKeyOf<INSite>.By<siteID>.Dirty
{
public static INSite Find(PXGraph graph, int? siteID)
=> FindBy(graph, siteID, (siteID ?? 0) <= 0);
}
public class UK : PrimaryKeyOf<INSite>.By<siteCD>
{
public static INSite Find(PXGraph graph, string siteCD)
=> FindBy(graph, siteCD);
}
}
Suppose that a DAC has multiple keys, and each of them can uniquely identify a record
in the database. To declare them all, you need to declare one primary key named
PK
and all other keys inside a unique key class named
UK
. An example is shown in the following code.
public partial class INUnit : PXBqlTable, IBqlTable
{
public class PK : PrimaryKeyOf<INUnit>.By<recordID>
{
public static INUnit Find(PXGraph graph, long? recordID) => FindBy(graph, recordID);
}
public abstract class UK
{
public class ByGlobal : PrimaryKeyOf<INUnit>.By<unitType, fromUnit, toUnit>
{
public static INUnit Find(PXGraph graph, string fromUnit, string toUnit) =>
FindBy(graph, INUnitType.Global, fromUnit, toUnit);
}
public class ByInventory : PrimaryKeyOf<INUnit>.By<unitType, inventoryID, fromUnit>
{
public static INUnit Find(PXGraph graph, int? inventoryID, string fromUnit) =>
FindBy(graph, INUnitType.InventoryItem, inventoryID, fromUnit);
}
public class ByItemClass : PrimaryKeyOf<INUnit>.By<unitType, itemClassID, fromUnit>
{
public static INUnit Find(PXGraph graph, int? itemClassID, string fromUnit) =>
FindBy(graph, INUnitType.ItemClass, itemClassID, fromUnit);
}
}
}
Coding Conventions
We recommend the following coding conventions, which are checked by Acuminator:
- A single unique key in a DAC declaration must have the name
UK
. - Multiple unique keys can have arbitrary names but they must be declared inside a
public static class named
UK
. - A DAC declaration must include at least one primary key declaration if you want to declare a unique key.
- Multiple unique keys cannot use the same set of fields.
- You cannot use unbound DAC fields in a unique key declaration for the same reason this recommendation applies for the primary keys. For details, see Restrictions.