Исключение в конечной точке из-за BqlDelegate - PullRequest
0 голосов
/ 13 июня 2018

У меня есть график, используемый экраном, к которому я получаю доступ через конечную точку веб-сервиса, например,

http://myserver/entity/MyEndpoints/17.200.001/MyEndpoint

На графике я определяю

    public PXSelectReadonly<MyDAC> Items;

и затем делегат для обслуживания элементов

    protected virtual IEnumerable items()

Когда я пытаюсь получить доступ к конечной точке, я получаю сообщение об ошибке:

    "There is a BqlDelegate in view Items"

и исключение типа PX.Api.ContractBased.OptimizedExport.CannotOptimizeException

Я нигде ничего не могу найти по этому вопросу, поэтому я немного озадачен.

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

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Acumatica пытается оптимизировать вызов API, «переводя» его на один SQL-запрос.Это делается путем просмотра определения вашей конечной точки, полей, которые вы хотите вернуть, и фактических запросов BQL, стоящих за ним.Если у вас есть делегат, он не может и не будет этого делать, если вы не скажете системе, что это «безопасно».

В прошлом Acumatica в конечном итоге молча выполняла выполнение делегатов., что приводит к очень низкой производительности при выполнении GetList() для большого набора данных.Хорошим примером является экран «Заказ на продажу»;за представлением транзакций (SOLine) есть делегат.Без этой оптимизации возврат всех заказов и строк заказа в одном вызове GetList() заставит систему вызывать делегат для каждого отдельного заказа, что приведет к сотням или даже тысячам запросов SQL!

В этом случае, однакоделегат используется только для кэширования некоторых данных, связанных со стоимостью товара, поэтому делегат представления «Транзакции» был помечен следующим атрибутом:

[Api.Export.PXOptimizationBehavior(IgnoreBqlDelegate = true)]
protected virtual IEnumerable transactions()

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

[Api.Export.NonOptimizable(IgnoreOptimizationBehavior = true)]
public class SomeGraph : PXGraph<SomeGraph>

Оптимизация не будет выполненаСистема и система будут вызывать делегата всегда.Это, скорее всего, приведет к более медленному, чем ожидалось, отклику, особенно когда делегат не является основным представлением.Есть еще один вариант этого атрибута, где вы можете идентифицировать определенные поля, которые нельзя оптимизировать;это приведет к включению оптимизации, если вы не включите эти поля как часть своей конечной точки:

[Api.Export.NonOptimizable(new Type[] { typeof(ARPayment.adjDate), typeof(ARPayment.curyApplAmt) })]

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

Обратите внимание, что эти атрибуты недокументированы и используются только для внутреннего использования.Мой совет - избегать их максимального использования, придерживайтесь простых графиков и выбирайте без делегатов, если это возможно ...

0 голосов
/ 13 июня 2018

Я использовал Jetbrains Dotpeek, чтобы покопаться в исходном коде Acumatica.

Нашел ответ на свой вопрос, который, по крайней мере, позволяет использовать график как

Добавление следующего объявления атрибутак классу графа позволяет использовать делегата

[NonOptimizable (IgnoreOptimizationBehavior = true)]

b

...