0

我们正在使用 uCommerce Stateless API 将产品批量导入 uCommerce (Umbraco),请参阅:https ://docs.ucommerce.net/ucommerce/v9.5/system-integration/bulk-import-from-third-party-systems .html

导入需要 12 个小时才能完成,这太慢了,我们需要引入并行性。

我们的代码在 .Net Framework 控制台应用程序中使用 async/await 模式。

我创建了一个 Task 类型的列表,然后使用 await Task.WhenAll(tasks); 并行执行

任务由以下方法返回。

但是,当为每个任务调用方法时,这会导致异常:

  • 外部异常:“将 DbDataReader 转换为
    NDataReader
    时出现问题”
  • 内部异常:“<strong>在有异步操作挂起时无法启动另一个操作”</li>

这似乎是 uCommerce/NHibernate 的潜在约束。我猜是因为它在某处共享一个 DBContext。

问:我们如何使用具有并行性的 uCommerce 无状态 API?

有没有办法获得 ISessionProvider 的独立实例?

public async Task ProcessProductAsync(dynamic currentProduct, PimApi api)
        {
            var statelessSession = ObjectFactory.Instance.Resolve<IStatelessSessionProvider>().GetStatelessSession();

            string sku = ExpandoHelper.GetListProperty(currentProduct, DynamicConstants.ParentsId);
            string variantSku = ExpandoHelper.GetProperty(currentProduct, DynamicConstants.PrimaryId);
            
            if (string.IsNullOrEmpty(sku) || string.IsNullOrEmpty(variantSku))
                return;

            var existingProduct = await statelessSession
                .Query<Product>()
                    .FetchMany(x => x.ProductDescriptions)
                        .ThenFetchMany(x => x.ProductDescriptionProperties)
                        .ThenFetch(x => x.ProductDefinitionField)
                    .FetchMany(x => x.CategoryProductRelations)
                        .ThenFetch(x => x.Category)
                    .FetchMany(x => x.ProductPrices)
                    .FetchMany(x => x.ProductProperties)
                    .Fetch(x => x.ProductDefinition)
                        .ThenFetch(x => x.ProductDefinitionFields)
                .SingleOrDefaultAsync(x => x.VariantSku == variantSku);
4

1 回答 1

0

我收到了 uCommerce Support 的回复,他们提供了以下信息:

您可以尝试的一件事是绕过“GetStatelessSession”。从容器中获得类型后,使用反射获取存储 sessionfactory(创建无状态会话)的以下属性,然后您可以打开一个新的再次无状态会话。您需要访问此属性:内部静态 ISessionFactory _factory;在此类型上:Ucommerce.EntitiesV2.SessionProvider "

当然 uCommerce 可能会改变其类的内部结构,因此上述方法很脆弱;但它确实有效。

当您从 IoC 容器解析类型时,您将拥有一个需要解包的 Castle Proxy。为此,我使用了以下代码:https ://stackoverflow.com/a/55671377/1053594

获得解包后的类后,您可以将其转换为 ISessionFactory 并调用 OpenStatelessSession 来创建新会话。我为列表中的每个任务执行此操作,并在方法完成时关闭会话。

于 2022-01-20T07:46:33.950 回答