# Epicor Function: How to Call a BAQ from C# (Functions and BPM)

> Source: https://netray.co/erp-help/epicor-function-call-baq-from-c-sharp
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

To run a BAQ from an Epicor Function or a BPM code block, call the Dynamic Query service: get the query's execution parameters by BAQ ID, set any parameter values, run it with the execute-by-ID method, and read rows from the results table. Declare the service in the function so the platform can resolve it.

## Kind

how-to

## System

epicor

## Erp

Epicor Kinetic

## Module

Epicor Functions / BPM

## Query

epicor function call baq

## Alternate Queries

- call baq from epicor function c#
- execute baq in bpm code epicor
- epicor dynamicquery executebyid

## Applies To

Epicor Kinetic Epicor Functions and BPM custom code. Service and type names have changed across versions, so verify them in your function editor's IntelliSense.

## Steps

### Call a BAQ from a function

**Items:**

- Create or open the function in Epicor Function Maintenance and add the request and response parameters you need.
- Add the Dynamic Query service contract to the function's services so CallService can resolve it.
- In the code, call the service with CallService and inside the callback get the execution parameter set for your BAQ ID.
- Set parameter values on the matching parameter rows, using the exact parameter names defined in the BAQ.
- Call the execute-by-ID method and read the Results table of the returned dataset.
- Loop the rows, map them to your response parameter, and return.
- Test in the function's test area with real parameters, then check security for the user or the API key calling the function.

## Sections

### Working pattern

**Body:**

The following sketch shows the common shape. Type names for the execution parameter dataset and result columns depend on your version, so let IntelliSense confirm them rather than copying blindly.

BAQ IDs and parameter names are case sensitive in practice, and a mismatch is the most frequent cause of a function that runs but returns nothing.

**Code:**

- // Inside an Epicor Function code block (names may vary by version)
- var result = new System.Collections.Generic.List<string>();
- this.CallService<Ice.Contracts.DynamicQuerySvcContract>(dq =>
- {
-     var qeds = dq.GetQueryExecutionParametersByID("MyJobsBAQ");
-     // set a parameter value on the parameter row named in the BAQ
-     var p = qeds.ExecutionParameter.NewExecutionParameterRow();
-     p.ParameterID = "JobNum";
-     p.ParameterValue = jobNum;
-     p.ValueType = "nvarchar";
-     p.IsEmpty = false;
-     qeds.ExecutionParameter.AddExecutionParameterRow(p);
-     var ds = dq.ExecuteByID("MyJobsBAQ", qeds);
-     foreach (var row in ds.Results.Rows)
-         result.Add(row["JobHead_JobNum"].ToString());
- });

### BAQ or direct data access

**Body:**

Calling a BAQ is useful when the query already exists, when business users maintain it, or when you want its security. For simple lookups inside server code, direct LINQ over the Db context in recent versions may be shorter and faster, since it avoids the dataset round trip. For anything report-like and reusable, keep the BAQ.

Remember that a BAQ called from a function runs with the calling user's rights. Calls from an API key or service account need that account to have access to the BAQ.

### Errors you will meet

**Body:**

A not found error on the BAQ ID means a typo or the query is not generated or not in the current company scope. Empty results with no error usually mean parameters did not bind, so check names and the value type. A permission error points at security on the BAQ or the calling account.

From a BPM, the same call works inside a custom code block, though heavy queries in a synchronous directive slow down the user's save, so move them to a post-processing or data directive design.

## Pitfalls

- Parameter ID typos, which bind nothing and return all or no rows.
- Calling a heavy BAQ from a synchronous BPM and slowing every save.
- Forgetting to generate the BAQ after editing it.
- Assuming the function runs with administrator rights.

## Ai Angle

An assistant that knows your BAQ catalog can suggest which existing query to call instead of writing a new one, and draft the function wrapper for a developer to review. Netray builds such developer-assist tools to run privately against your Epicor environment, including on-prem installs.

## Faq

### How do I run a BAQ from C# in Epicor?

**Answer:** Call the Dynamic Query service from the function or BPM code, set the parameters on the execution parameter set, then use execute-by-ID and read the Results table of the returned dataset.

### Can I call a BAQ from a BPM directive?

**Answer:** Yes, in a custom code block with the same service call. Avoid heavy queries in pre-processing directives since they block the user's action.

### Why does my function return no rows?

**Answer:** Usual causes are a wrong parameter ID, a wrong value type, the BAQ not generated, or criteria excluding everything. Test the BAQ with the same parameters in the Query Builder first.

### Should I use a BAQ or LINQ on Db?

**Answer:** Use a BAQ for existing, shareable and user-maintained queries. For simple, performance sensitive lookups in server code, direct LINQ can be simpler, if your version supports it.

## Search terms

epicor function call baq, call baq from c# epicor, epicor bpm run baq, epicor dynamicquery executebyid, epicor function baq parameter, epicor kinetic function code, execute baq in epicor function, epicor callservice dynamicquerysvc

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
