0

我在 PreferencesGeneral 中添加了一个名为 UsrShortCompanyName 的自定义字段。我需要一个静态方法,它应该返回一个字典,其中 Key == Company.CompanyKey 和 Value == PreferencesGeneral.UsrShortCompanyName。所以,我需要 Acumatica 的 ORM 来执行一个如下所示的 sql 查询:

select c.CompanyKey, p.UsrCompanyShortName from Company c inner join PreferencesGeneral p on p.CompanyID = c.CompanyID where c.CompanyType != 'System'

我有几个问题:

  1. PXSelect 在当前公司范围内执行查询,因此它会自动添加条件“WHERE CompanyID = <CurrentCompanyId>”。是否可以阻止 ORM 添加此公司限制?

  2. PreferencesGeneral 和 Company DAC 都不包含 CompanyID 字段,因此我无法编写类似

PXSelectJoin<PX.Objects.GL.Company, InnerJoin<PreferencesGeneral, On<PX.Objects.GL.Company.companyId, Equal<PreferencesGeneral.companyId>>>>

在这种情况下我该怎么办?

  1. 是否有可能使用 Acumatica 的 ORM 执行普通 SQL?我发现的唯一类似函数是 PXDatabase.Execute 方法,但它只能用于存储过程,并且只有在 SP 具有 OUTPUT 参数时才会返回数据。但在我的情况下,它不是一个选项,因为 OUTPUT 参数不能是 TABLE 类型。

我发现的唯一解决方法是在新的 SqlConnection 范围内执行我的 sql 查询,但在这种情况下,我需要获得与 Acumatica 的 ORM 相同的连接字符串。我想知道 Acumatica 如何确定它是否应该在 Web.config(如果它是本地或 QA 服务器)或 Azure 配置(用于生产)中搜索连接字符串。

感谢帮助。

4

1 回答 1

1

The isolation of companies is strongly enforced by BQL, and you won't be able to retrieve data from another company unless you're logged into this company. The ORM also takes care of returning you the data from other company IDs if this data is split/shared with another company. As you have noticed, for tables that don't contain a CompanyID field, the system returns all the data contained in this table.

You are also not allowed to run direct SQL queries unless you go through a stored procedure, and you won't be able to open a SqlConnection unless you modify the default security policy (SqlClientPermission inside web_project_x.config). Allowing direct SQL queries could potentially make the application vulnerable to SQL injection, and also makes the data of other companies 'permeable' -- although most installations use a separate database for each registered customer, Acumatica is also used in fully multi-tenant environments, and we need to ensure there is proper isolation between the tenants (customers).

If you are developing an ISV solution that is intended for multiple Acumatica customers, I would strongly advise that you avoid techniques to bypass the ORM. Such solutions will not be certified by Acumatica and I consider them suitable only for one-off customizations. Instead, you can use one of the following ways to get to your data:

  • Create a special table without a CompanyID which would store data available to all companies
  • Use web services to connect to other companies
  • Use a PXLoginScope block to temporarily run code under the identify of another user in another company
  • Create a SQL View that is bound to a BQL table of the same name
  • Call a SQL stored procedure which aggregates data from multiple companies (and omit the CompanyID field in the resulting view)

Another argument for sticking with BQL is that your code will work transparently on MySQL and SQL Server. If you rely on a SQL view or stored procedure, you will have to create different versions to support both platforms.

于 2014-12-03T07:57:50.333 回答