Acumatica — Уникальная проверка

#unique #acumatica

#уникальная #acumatica

Вопрос:

Какой атрибут можно использовать, чтобы разрешить уникальные значения, мы использовали [PXUniqueCheck(typeof(Name))] Но если используется представление списка и записи обновляются с тем же именем, оно допускает одинаковые значения имени

Более подробно — ПРИВЕТ, столбец отмечен IsKey = True для имени, мое представление — ListView, с двумя полями Name и Description, где Name имеет IsKey = True, а другой идентификатор столбца имеет атрибут DBIdentity. ИТАК, я думаю, что с DAC все в порядке, пользовательский интерфейс добавляет поведение — когда добавляется существующее значение, оно обновляет старую строку новым добавленным описанием значения, поскольку имя такое же. Поведение обновления — Измените столбец name на то же значение, что и у other, тогда это позволит иметь 2 строки с одинаковым ключом, но обе строки отображают одно и то же описание в пользовательском интерфейсе, но в DB есть 2 строки с одинаковым значением Name и разным описанием

DAC —

 [System.SerializableAttribute()]
[PXPrimaryGraph(typeof(TestCategoryMaint))]
public class TestCategory : PX.Data.IBqlTable
{

    #region TestCategoryID
    public abstract class testCategoryID : PX.Data.BQL.BqlInt.Field<testCategoryID>
{
    }
    protected int? _TestCategoryID;
    [PXDBIdentity()]
    [LicenseExpiration]
[PXReferentialIntegrityCheck]

public virtual int? TestCategoryID
    {
        get
        {
            return this._TestCategoryID;
        }
        set
        {
            this._TestCategoryID = value;
        }
    }
    #endregion

    #region Name
    public abstract class name : PX.Data.IBqlField
    {
    }
    protected string _Name;
    [PXDBString(50, IsKey = true, IsUnicode = true, InputMask = "")]
    [PXDefault()]        
    [PXUIField(DisplayName = "Test Category")]
    [PXCheckUnique(typeof(name))]
    public virtual string Name
    {
        get
        {
            return this._Name;
        }
        set
        {
            this._Name = value;
        }
    }
    #endregion

    #region Description
    public abstract class description : PX.Data.IBqlField
    {
    }
    protected string _Description;
    [PXDBString(255,IsUnicode =true)]
    [PXUIField(DisplayName = "Description")]
    public virtual string Description
    {
        get
        {
            return this._Description;
        }
        set
        {
            this._Description = value;
        }
    }
#endregion
  

Комментарии:

1. Если вам нужны уникальные значения, рассматривали ли вы возможность добавления IsKey в ваше поле DAC? Похоже, что ваше поле является каким-то типом первичного ключа

2. Iskey добавляется в столбец Identity, который также используется в справочных таблицах, в то время как Name является полем CD

3. Вы можете использовать IsKey в поле CD и по-прежнему использовать столбец identity (без ключа) в качестве ссылки в других таблицах. Ключи таблицы SQL могут отличаться от ключа DAC, что нормально.

4. Дмитрий, да, имя присваивается с помощью IsKey true, но все же в режиме просмотра списка мы можем воспроизвести наличие 2 строк с одинаковыми именами, обновив существующую строку с тем же именем, что и уже имеющуюся в другой строке, а затем она отобразит обе строки с одинаковым значением в пользовательском интерфейсе.

Ответ №1:

Без каких-либо примеров кода того, что вы пытаетесь сделать, трудно гарантировать, что ответ соответствует вашему вопросу, но я постараюсь ответить в широком масштабе.

Основываясь на приведенных выше комментариях, поле идентификации является таковым именно потому, что оно определено как идентификатор в базе данных. Соответствующее поле в DAC должно быть помечено как PXDBIdentity. В Acumatica это обычно определяется как поле идентификатора «ID». Отображаемое вами поле, которое должно оставаться уникальным, как правило, является полем code «CD».

Приведенный ниже пример показывает, как настроить пару, в комплекте с часто используемыми атрибутами. В этом примере поле CD пронумеровано автоматически, но это не обязательно. PXSelector в самом поле помогает сохранить это как уникальное значение, поскольку это позволит вам выбирать из существующего значения, вводить новое значение или извлекать значение, которое было введено с помощью ключа. Фактическая уникальность контролируется комбинацией всех полей, отмеченных IsKey = true.

 // This is the Identity field in the database (Use PXDBIdentity)
#region RequisitionID
[PXDBIdentity]
public virtual int? RequisitionID { get; set; }
public abstract class requisitionID
    : PX.Data.BQL.BqlInt.Field<requisitionID> { }
#endregion

// This is the user friendly Code (CD) to be unique (IsKey = true)
#region RequisitionCD
[PXDBString(30, IsKey = true, IsUnicode = true, InputMask = "")]
[PXDefault]
[AutoNumber(typeof(SSRQSetup.requisitionNumberingID),
    typeof(AccessInfo.businessDate))]
[PXSelector(
    typeof(SSRQRequisition.requisitionCD),
    typeof(SSRQRequisition.requisitionCD),
    typeof(SSRQRequisition.descr)
    )]
[PXUIField(DisplayName = Messages.FldRequisitionCD)]
public virtual string RequisitionCD { get; set; }
public abstract class requisitionCD
    : PX.Data.BQL.BqlString.Field<requisitionCD> { }
  

Аналогичным образом, вы можете вернуться к этой комбинации, чтобы при взаимодействии с пользователем использовалось уникальное поле CD, но значение ID сохранялось в записи. Лучше всего использовать поле ID, которое будет общим для всех таблиц, где используется для нормализации базы данных и позволяет изменять отображаемое значение (CD) без необходимости потенциально обновлять десятки других таблиц. Это означает, что любой уникальный объект (товар, поставщик, клиент и т.д.) будет сохраняться в его собственной записи, где значение IsKey однозначно идентифицирует точный объект. Если вам нужно, чтобы ваша конкретная таблица сохраняла это значение в качестве уникальности, то это было бы единственное поле с пометкой IsKey = true, а затем поле identity использовалось бы в других таблицах, ссылающихся на эти данные.

Чтобы использовать эти ключевые данные в других таблицах, вам следует сохранить значение поля ID, но использовать PXSelector для представления значения CD пользователю. Это позволяет хранить очень эффективное числовое значение в базе данных в связанных таблицах, а не значение, которое может состоять из нескольких символов или тысяч символов (в крайнем случае).

 #region RequisitionID
[PXDBInt]
[PXSelector(
    typeof(SSRQRequisition.requisitionID),
    typeof(SSRQRequisition.requisitionCD),
    typeof(SSRQRequisition.descr),
    SubstituteKey = typeof(SSRQRequisition.requisitionCD)
    )]
[PXUIField(DisplayName = Messages.FldRequisitionID)]
public virtual int? RequisitionID { get; set; }
public abstract class requisitionID
    : PX.Data.BQL.BqlInt.Field<requisitionID> { }
#endregion
  

Очень важно понимать, что использование IsKey обеспечит уникальность на основе каждого поля, в котором вы его указали. IsKey обеспечит уникальность только для комбинации всех полей, отмеченных IsKey = true. Похоже, что PXSelector гарантирует, что само поле сохраняется уникальным, а также поле, указанное с помощью SubstituteKey, при использовании в качестве селектора будет извлекать запись, содержащую введенное вами значение. Я использовал это только в случаях ID против CD, но вы могли бы поэкспериментировать с PXSelector и IsKey, если у вас есть какой-либо вариант использования, выходящий за рамки этого ответа.

Комментарии:

1. ПРИВЕТ, столбец отмечен IsKey = True для имени, мое представление — ListView, с двумя полями Name и Description, где Name имеет IsKey = True, а другой идентификатор столбца имеет атрибут DBIdentity. ИТАК, я думаю, что с DAC все в порядке, пользовательский интерфейс добавляет поведение — когда добавляется существующее значение, оно обновляет старую строку новым добавленным описанием значения, поскольку имя такое же. Поведение обновления — Измените столбец name на то же значение, что и у другого, тогда это позволит иметь 2 строки с одинаковым ключом, но обе строки отображают одинаковое описание в пользовательском интерфейсе, но в базе данных есть 2 строки с одинаковым значением имени и разным описанием.

2. Пожалуйста, обновите свой вопрос, чтобы предоставить код для вашего DAC. Любое поле, которое не помечено как IsKey = true или помечено как identity или с использованием PXParent, должно быть в порядке исключения.

Ответ №2:

Приведенный ниже код поможет вам добавлять только уникальные значения, и когда вы пытаетесь добавить повторяющиеся значения, это выдает ошибку.

 [PXCheckUniqueCustomError("Order already exists with Customer Order Nbr {0} and External Ref.Nbr {1}", typeof(SOOrder.customerOrderNbr), typeof(SOOrder.customerRefNbr),  
Where = typeof(Where2<Where<SOOrder.orderType, Equal<Current<SOOrder.orderType>>,
    And<SOOrder.customerOrderNbr, Equal<Current<SOOrder.customerOrderNbr>>,
        And<SOOrder.customerRefNbr, Equal<Current<SOOrder.customerRefNbr>>>>>,
And<SOOrder.status, NotEqual<SOOrderStatus.cancelled>>>))]