如何将 BQL In Operator 与 Select2 查询/PXProjection 和值列表一起使用

How to use BQL In Operator with Select2 query / PXProjection and list of values

我正在尝试复制您可以在 SQL 服务器中执行的以下类型的 SQL 查询...这里的重要部分是 WHERE 子句: Select InventoryItem 的 InventoryCD WHERE InventoryCD IN ('123123', '154677', '445899', '998766')

它使用 IN3<> 运算符和一系列字符串常量完美运行: 即 And,

但是,我需要能够使用数组中任意长的值列表来执行此操作,并且我需要能够在运行时动态设置这些值。

我不确定我需要将什么类型传递给 PXProjection 查询中的 IN<> 语句。我一直在尝试以下方法,但这会引发编译器错误。

public class SOSiteStatusFilterExt : PXCacheExtension<SOSiteStatusFilter>
{
    public static bool IsActive()
    {
        return true;
    }
    public abstract class searchitemsarray : PX.Data.IBqlField
    { 
    }
    [PXUnboundDefault()]
    public virtual string[] Searchitemsarray { get; set; }

}

我想也许我需要一个 PXString 对象数组?我真的不确定,也没有任何有用的文档。有人可以帮忙吗?

这显示了如何使用普通 PXSelect:https://asiablog.acumatica.com/2017/11/sql-in-operator-in-bql.html

但我需要能够使用 Select2...

传递正确的类型

作为参考我会post这里the example mentioned by Hugues评论。

如果您需要使用在运行时生成的任意值列表生成查询,如下所示:

Select * from InventoryItem InventoryItem
Where InventoryItem.InventoryCD IN ('123123', '154677', '445899', '998766')
Order by InventoryItem.InventoryCD

你会这样写:

Object[] values = new String[] { "123123", "154677", "445899", "998766" };

InventoryItem item = PXSelect<InventoryItem,
      Where<InventoryItem.inventoryCD,
      In<Required<InventoryItem.inventoryCD>>>>.Select(Base, values);

请注意 In<> operator is available only with Required<> 参数,您需要手动将可能值的数组传递给 Select(…) 方法参数。所以你需要在调用 Select 方法之前用你的列表填充这个数组。

此外,Required<> parameter should be used only in the BQL statements that are directly executed in the application code. The data views that are queried from the UI will not work if they contain Required<> 参数。

我最终创建了 100 个变量并使用了 BQL OR 运算符,即

  And2<Where<InventoryItem.inventoryCD, Equal<CurrentValue<SOSiteStatusFilterExt.Pagefilter1>>,
        Or<InventoryItem.inventoryCD, Equal<CurrentValue<SOSiteStatusFilterExt.Pagefilter2>>,
        Or<InventoryItem.inventoryCD, Equal<CurrentValue<SOSiteStatusFilterExt.Pagefilter3>>,
        Or<InventoryItem.inventoryCD, Equal<CurrentValue<SOSiteStatusFilterExt.Pagefilter4>>,

 etc...etc...

然后您可以在 SOSiteStatusFilter.inventory 的 FieldSelecting 事件中设置 Pagefilter1、2 等的值,例如。这里的关键洞察力,对于 Acumatica 的外行来说并不那么明显,是 SQL 服务器中通过 BQL 参数化的所有变量都是可以为空的。如果查询为 运行 时变量为 null,SQL 服务器会使用“位翻转”方法自动禁用该变量,以在 SQL 过程调用中禁用该变量。在正常的 T-SQL 中,这会引发错误。但是 Acumatica 的框架通过在评估相等性之前在 SQL 过程中禁用该变量来处理 NULL 字段相等性的情况。

这种方法的性能非常好,尤其是因为我们在索引键字段上进行查询(从技术上讲,InventoryCD 不是主键,但它基本上是紧随其后的)。