Acumatica -选择从返回Null尽管传递一个有效的ID



我正在创建Acumatica的EmployeeMaint图的扩展。在我创建的自定义Action中,我需要访问与员工分支相关联的BAccount:

public PXAction<EPEmployee> CreatePREmp;
[PXButton]
[PXUIField(DisplayName = "Import Employee", MapEnableRights = PXCacheRights.Insert, MapViewRights = PXCacheRights.Insert)]
public IEnumerable createPREmp(PXAdapter adapter)
{
var employeeSettingsGraph = PXGraph.CreateInstance<PREmployeePayrollSettingsMaint>();
PREmployee payrollEmployee = PayrollEmployee.SelectSingle();
if (payrollEmployee == null)
{
var bID = Base.Employee.Current.ParentBAccountID.GetValueOrDefault();
Branch branch = SelectFrom<Branch>
.Where<Branch.bAccountID.IsEqual<@P.AsInt>>.View.Select(Base, bID);
BAccount bAccount = SelectFrom<BAccount>
.Where<BAccount.bAccountID.IsEqual<@P.AsInt>>.View.Select(Base, bID);
// Code removed for brevity
return adapter.Get();
}
else
{
throw new Exception("Employee already exists!");
}
}

SelectFrom<BAccount>语句是问题所在。它返回null,即使我已经通过调试和查看底层DB验证bID确实有效。此外,它前面的语句(SelectFrom<Branch>)工作得很好,我认为如果bID没有与有效的BAccount关联,则不会出现这种情况。

如有任何提示,我将不胜感激。

由于没有指定版本,我的测试是针对2021 R1进行的。

您遇到的问题是,在EmployeeMaint图上已经有了BAccount的数据视图。一般来说,不应该在给定的图上为相同的数据访问类提供多个数据视图。我知道有一些例外,但我不知道具体是什么。当您发现自己处于这种情况时,通常会发生的情况是生成的SQL具有join,并且来自多个声明的数据视图的条件用于数据访问类,最终强制查询不返回任何内容。

要解决这个问题,有几个解决方案(按照我可能使用的顺序列出,尽管所有的测试都成功了)。

解决方案1 -使用BAccount.PK.Find

在最近的Acumatica版本(20r2)中,他们在数据访问类中添加了一个PK类。该类有一个静态函数Find,该函数根据键值检索记录。我不知道所有的规则,但我从来没有遇到过数据访问类在图上存在数据视图的问题。如果按ID检索,这似乎是最干净的代码。

public PXAction<EPEmployee> CreatePREmp;
[PXButton]
[PXUIField(DisplayName = "Import Employee", MapEnableRights = PXCacheRights.Insert, MapViewRights = PXCacheRights.Insert)]
public IEnumerable createPREmp(PXAdapter adapter)
{
var employeeSettingsGraph = PXGraph.CreateInstance<PREmployeePayrollSettingsMaint>();
PREmployee payrollEmployee = employeeSettingsGraph.PayrollEmployee.SelectSingle();
if (payrollEmployee == null)
{
var bID = Base.Employee.Current.ParentBAccountID.GetValueOrDefault();
Branch branch =
SelectFrom<Branch>
.Where<Branch.bAccountID.IsEqual<@P.AsInt>>
.View.Select(Base, bID);
BAccount bAccount = BAccount.PK.Find(Base, bID);
// Code removed for brevity
return adapter.Get();
}
else
{
throw new Exception("Employee already exists!");
}

解决方案2 -使用不同的数据访问类

您可以使用指向相同数据的不同数据访问类(不在图上的数据视图中)。由于BAccount是一个通用的,Acumatica已经有了BAccount2,可以在这个实例中用于此目的。

public PXAction<EPEmployee> CreatePREmp;
[PXButton]
[PXUIField(DisplayName = "Import Employee", MapEnableRights = PXCacheRights.Insert, MapViewRights = PXCacheRights.Insert)]
public IEnumerable createPREmp(PXAdapter adapter)
{
var employeeSettingsGraph = PXGraph.CreateInstance<PREmployeePayrollSettingsMaint>();
PREmployee payrollEmployee = employeeSettingsGraph.PayrollEmployee.SelectSingle();
if (payrollEmployee == null)
{
var bID = Base.Employee.Current.ParentBAccountID.GetValueOrDefault();
Branch branch =
SelectFrom<Branch>
.Where<Branch.bAccountID.IsEqual<@P.AsInt>>
.View.Select(Base, bID);
BAccount2 bAccount = 
SelectFrom<BAccount2>
.Where<BAccount2.bAccountID.IsEqual<@P.AsInt>>
.View.Select(Base, bID);
// Code removed for brevity
return adapter.Get();
}
else
{
throw new Exception("Employee already exists!");
}

解决方案3 -使用不同的图

您可以为您的查询使用不同的图形上下文,其中图形上下文没有引用所需的数据访问类的数据视图。注意,在这个例子中,我使用了新的PXGraph()。文档总是说不要使用新的操作符进行图形实例化,但是我从Acumatica开发人员那里得到了代码(至少5次),在那里他们使用了新的PXGraph()来解决这个问题。

public PXAction<EPEmployee> CreatePREmp;
[PXButton]
[PXUIField(DisplayName = "Import Employee", MapEnableRights = PXCacheRights.Insert, MapViewRights = PXCacheRights.Insert)]
public IEnumerable createPREmp(PXAdapter adapter)
{
var employeeSettingsGraph = PXGraph.CreateInstance<PREmployeePayrollSettingsMaint>();
PREmployee payrollEmployee = employeeSettingsGraph.PayrollEmployee.SelectSingle();
if (payrollEmployee == null)
{
var bID = Base.Employee.Current.ParentBAccountID.GetValueOrDefault();
Branch branch =
SelectFrom<Branch>
.Where<Branch.bAccountID.IsEqual<@P.AsInt>>
.View.Select(Base, bID);
BAccount bAccount = 
SelectFrom<BAccount>
.Where<BAccount.bAccountID.IsEqual<@P.AsInt>>
.View.Select(new PXGraph(), bID);
// Code removed for brevity
return adapter.Get();
}
else
{
throw new Exception("Employee already exists!");
}

最新更新