我在尝试构建表格数据库然后将其作为语义模型部署到 Power BI 工作区的控制台应用程序 (.NET Framework 4.7.2) 中经常遇到问题。
每当我尝试检索新添加的数据库或访问数据库的模型对象时,我经常遇到 AmoExceptions 或 NullReferenceExceptions,特别是在部署数据库后很快尝试这样做(即使我可以通过 PowerBI 查看数据库)网站)。
我已经能够通过重试逻辑编码来稍微减少不稳定性,但这在开发环境之外似乎站不住脚且不可持续。
例如,下面的(简化的)代码尝试将临时数据库的模型与标准(非临时)数据库的模型交换。
这是我的代码:
// C# code
// Previous code to deploy Power BI database to PBI Workspace
Microsoft.AnalysisServices.Tabular.Server PBIServer = new Microsoft.AnalysisServices.Tabular.Server();
PBIServer.Connect(PowerBIConnectionString);
Microsoft.AnalysisServices.Tabular.Database tabularCubeFrom = PBIServer.Databases.FindByName(TabularCubeTemporaryName);
Microsoft.AnalysisServices.Tabular.Database tabularCubeTo = PBIServer.Databases.FindByName(TabularCubeName);
tabularCubeFrom.Model.CopyTo(tabularCubeTo.Model);
// Code to save changes, disconnect, etc.
上面的代码(以及相关代码)中出现了两个类似的错误:
如果我调试问题,然后在稍有延迟后重试代码,那么数据库和模型将被填充。同样,在稍有延迟后重试错误代码几次的逻辑会降低不稳定性,但我不这样做我不相信这是一个好的“解决方案”。
是否有可靠的方法来确保 Model 对象完全加载,而无需特殊逻辑在延迟后重试?
您遇到的问题可能是由于将表格数据库部署到 Power BI 工作区可能需要一些时间才能完全初始化,即使部署在 Power BI 门户上可见之后也是如此。
FindByName()
方法可能会在模型完全准备好之前返回数据库对象,这就是您遇到间歇性 NullReferenceException
和 AmoException
错误的原因。
发生这种情况的原因是,尽管部署过程已完成且数据库可见,但 Power BI(或 Analysis Services)可能仍在最终确定模型结构并使其可通过 API 进行访问的过程中。这种类型的行为在涉及异步进程的服务(例如 Power BI)中并不罕见。
您可以采取一些方法来可靠地检查数据库是否准备就绪:
您可以添加检查以确保在继续之前数据库的模型已完全加载并可访问,而不是仅仅依赖具有任意延迟的重试逻辑。这可以通过轮询数据库的
State
属性以确保其处于 Ready
状态来完成,这确认部署和初始化已完成。
以下是实施此方法的方法:
public Microsoft.AnalysisServices.Tabular.Database WaitForDatabaseReady(
Microsoft.AnalysisServices.Tabular.Server server,
string databaseName,
int maxRetries = 10,
int delayBetweenRetriesInSeconds = 5)
{
for (int i = 0; i < maxRetries; i++)
{
var database = server.Databases.FindByName(databaseName);
if (database != null && database.Model != null && database.State == Microsoft.AnalysisServices.Tabular.ObjectState.Ready)
{
// Database and model are fully initialized and ready
return database;
}
// Wait for a bit before retrying
Thread.Sleep(delayBetweenRetriesInSeconds * 1000);
}
throw new Exception($"Database '{databaseName}' was not ready after {maxRetries} attempts.");
}
在此代码中:
State == ObjectState.Ready
检查数据库是否完全初始化。Model
属性,从而防止 NullReferenceException
或 AmoException
错误。如果模型初始化需要时间,您可能还需要显式调用
Database
对象的 Refresh()
方法以确保从服务器检索最新状态。如果客户端上的缓存版本与服务器的状态不完全同步,这会很有用:
PBIServer.Refresh(); // Ensures that the server object has the most up-to-date state.
tabularCubeFrom.Refresh();
tabularCubeTo.Refresh();
这可确保您使用数据库及其模型的最新状态。
当后端负载不足时,Power BI API 有时可能会限制请求或出现延迟。如果即使在执行上述检查后问题仍然存在,请确保您的应用程序没有达到速率限制。