从 Azure CosmosDB 加载的 F# 脚本中缺少 DLL 异常



我正在尝试针对我的 Azure CosmosDB 测试 F# 脚本文件中的一些不同查询,但在尝试执行查询本身时收到有关缺少 DLL 的错误。

我正在加载Documents.Client.dll

#r "../packages/Microsoft.Azure.DocumentDB/lib/net45/Microsoft.Azure.Documents.Client.dll"
open Microsoft.Azure.Documents
open Microsoft.Azure.Documents.Client
open Microsoft.Azure.Documents.Linq

但是当我执行查询时:

Seq.toList <| query {
//some query that I copy & pasted from a working file
}

我收到此错误:

System.AggregateException: One or more errors occurred. ---> System.DllNotFoundException: Unable to load DLL 'Microsoft.Azure.Documents.ServiceInterop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at Microsoft.Azure.Documents.ServiceInteropWrapper.CreateServiceProvider(String configJsonString, IntPtr& serviceProvider)
at Microsoft.Azure.Documents.Query.QueryPartitionProvider.Initialize()
at Microsoft.Azure.Documents.Query.QueryPartitionProvider.GetPartitionedQueryExecutionInfoInternal(SqlQuerySpec querySpec, PartitionKeyDefinition partitionKeyDefinition, Boolean requireFormattableOrderByQuery, Boolean isContinuationExpected)
at Microsoft.Azure.Documents.Query.DocumentQueryExecutionContextBase.<GetPartitionedQueryExecutionInfoAsync>d__0.MoveNext()

(堆栈跟踪中还有更多内容 - 这只是它的顶部(。

我在任何地方都找不到ServiceInteropdll - 它没有在任何项目或我的包文件夹中引用,也不是 nuget 引用。我不确定我可能会错过什么,只能在 F# 交互式中收到此错误。

更新

按照 @tomislav-markovski 评论中的建议,我将Microsoft.Azure.DocumentDB的版本更改为 1.13.2。这确实会在包文件夹中创建ServiceInteropdll,但现在在 F# 交互式中运行我的查询会给出以下输出:

--> Referenced 'c:VSTSMyApplication../packages/Microsoft.Azure.DocumentDB/lib/net45/Microsoft.Azure.Documents.Client.dll' (file may be locked by F# Interactive process)

Script.fsx(5,1): error FS0229: Error opening binary file 'c:VSTSMyApplication../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll': c:VSTSMyApplication../packages/Micro
soft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll: bad cli header, rva 0

Script.fsx(5,1): error FS3160: Problem reading assembly 'c:VSTSMyApplication../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll': Exception of type 'Microsoft.FSharp.Compiler.ErrorLogger+
StopProcessingExn' was thrown.

"文件可能被锁定"错误似乎很重要,但我关闭并重新打开了VSCode,以确保F#交互的实例没有保留任何内容。我正在引用服务互操作文件:

#r "../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll"

如果我删除它,上述错误就会消失......我回到查询本身,因为缺少 DLL。

更新 2

我尝试了一些其他方法:

  1. 绝对路径而不是Client.dll的相对路径。这会导致"缺少服务互操作 dll"错误。
  2. 绝对路径,而不是指向"服务互操作.dll"的相对路径。这会导致"打开二进制文件时出错"错误。
  3. 使用#I以更简单的路径加载 DLL:

    #I "../packages/Microsoft.Azure.DocumentDB/lib/net45/"

    #r "Microsoft.Azure.Documents.Client.dll"

    导致相同的"缺失ServiceInterop.dll"错误。

  4. 简化查询:

    Seq.toList <| query { for t in client.CreateDocumentQuery( documentCollectionUri()) do select t }

这导致了相同的"缺少ServiceInterop.dll"错误。 5. 将源选项与"启用跨参与者查询"一起使用:

let feedOptions = FeedOptions()
feedOptions.EnableCrossPartitionQuery <- true
feedOptions.MaxItemCount <- 3 |> System.Nullable
Seq.toList <| query {
for t in client.CreateDocumentQuery( documentCollectionUri(), feedOptions ) do
select t
}

如您所见,我还尝试设置最大项目计数。这两者都给出了相同的"缺失ServiceInterop.dll"错误。

我能够找到的最接近解决方案的是将 ServiceInterop.dll 的位置添加到 FSI 会话期间的 Path 环境变量中,如下所示:

open System
open System.IO
// get existing contents of path env var
let path = Environment.GetEnvironmentVariable("Path") 
// get location where nuget puts the service interop dll
let serviceInteropDir = @C:User<USERNAME>.nugetpackagesmicrosoft.azure.documentdb.core1.9.1runtimeswinnative"
// add service interop location to the end of the path
let newPath = path + ";" + serviceInteropDir
// update the path env var with the new path
Environment.SetEnvironmentVariable("Path", newPath)

注意:请注意,我使用的是 DocumentDB.Core 包的 1.9.1 版。DocumentDB.Core 包的 1.10.0 版本似乎存在严重的命名问题,因此在发布修补程序或找到解决方法之前,请避免使用该版本。

最新更新