0

有没有人在 CLR 存储过程中使用过 Solrnet?我真的很感激一些好的教程的指针。

我面临的一个问题是我找不到将 SolrNet 库作为对 VS (2008) Database (SQL Server) 项目的引用的方法。

更新:

所以看起来当你有一个 SQL Server 项目,并且你想添加对库的引用时,它必须首先存在于 SQL Server 本身中,这是有道理的。这是通过使用以下 SQL 从 DLL 本身在 SQL Server 中创建程序集来完成的:

CREATE ASSEMBLY SolrNet FROM 'C:\CLR_SP\SolrNet.dll' 
WITH   PERMISSION_SET = UNSAFE

(请注意,UNSAFE可能会对数据库的安全性产生一些影响,但现在对我来说还可以)

但是 SolrNet.dll 需要其他库依赖项,例如Castle.Windsor.dll(它本身需要System.Core.dll)和Ninject.dll。我找到了所需版本的Castle.Windsor.dll(即 2.5.1.0)和System.Core.Dll(位于 Windows 的 .Net 文件夹中),但是我找不到所需版本的Ninject.dll(其中应该是 2.1.0.76)。我试图创建程序集版本 2.2,但正如预期的那样,它没有完成这项工作。

我在不同的存储库上搜索它,但找不到它。有谁知道我在哪里可以找到这个版本的 DLL?

更新 2:

所以在网上搜索了很多之后,我仍然没有找到Ninject.dll v2.1.0.76。我的下一个尝试是使用 SolrNet 的下一个版本(即 v0.4.0.2002)。这个版本需要我已经找到的Ninject.dll v2.2 。所以我目前的状态是在 SQL Server 中注册所有其他依赖于SolrNet.dll的库。我将保留此文件以记录我的过程,以防有人遇到同样的问题。

更新 3:

我已经设法注册了所有必需的库(其中一些是我从GitHub 上的 SolrNet 源获得的)。所以现在,SolrNet 在 SQL Server 中注册为程序集,因此我可以从 .NET SQL Server 项目(用于创建 CLR 存储过程)中引用它。所以我编写了一个非常简单的 CLR SP,它连接到 SOLR 并检索一条数据。下面的代码:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void PrintToday()
{
    SqlPipe p;
    p = SqlContext.Pipe;
    p.Send("Helloooo");

    // Open Solr instance
    SolrNet.Startup.Init<ActiveProduct>("http://192.168.2.190:8983/solr");

    // Get instance of ActiveProduct
    ISolrOperations<ActiveProduct> operations = ActiveProduct.GetActiveProductSolrOperations();

    // Prepare QueryOptions. This will be passed as a parameter into the query() method.
    SolrNet.Commands.Parameters.QueryOptions qo = new QueryOptions();

    qo.Start = 0;
    qo.Rows = 20;

    // Query Solr
    SolrQueryResults<ActiveProduct> results = operations.Query(new SolrQueryByField("SearchDescription", "pants"), qo);

    // Read results
    String s = "Docs found: " + results.NumFound;
    p.Send(s);
}

我的下一个问题是,当我部署和运行 CLR SP 时,弹出一个错误,指出 Solr 已在容器中注册。我在 SQL Server Management Studio 中看到的确切输出如下:

Helloooo
Msg 6522, Level 16, State 1, Procedure PrintToday, Line 0
A .NET Framework error occurred during execution of user defined routine or aggregate 'PrintToday': 
System.ApplicationException: Key 'SolrNet.Impl.SolrConnection.CLRStoredProcedures2.ActiveProduct.SolrNet.Impl.SolrConnection' already registered in container
System.ApplicationException: 
   at SolrNet.Utils.Container.Register(String key, Type serviceType, Converter`2 factory)
   at SolrNet.Utils.Container.Register[T](String key, Converter`2 factory)
   at SolrNet.Startup.Init[T](ISolrConnection connection)
   at SolrNet.Startup.Init[T](String serverURL)
   at StoredProcedures.PrintToday()

PrintToday是 CLR StoredProcedure 的名称

CLRStoredProcedures2是 .NET SQL Server 项目的名称和 VS 2008 中的默认命名空间

ActiveProduct是 Solr 中文档的名称,带有 Solr 注解的 cs 类

从输出中可以看出,第一个Pipe.send("Hellooo")是完成它的工作,因此 SP 工作正常,直到那里。

当我搜索上述错误时,我发现它会显示何时尝试在同一应用程序中注册 Solr 实例两次。现在我看不到我在哪里注册了两次实例。我在这里错过了什么吗?

请注意,当在我的机器上开发的 cs 控制台应用程序中执行时,上述 cs 函数运行良好。另一个可能很重要的细节是 SOLR 服务器托管在我的机器上,该机器与我的 SQL Server 2005 位于同一网络上。

更新 4:

对于初学者,我上面提到的错误(在更新 3 中)在部署后第一次执行 SP 时不会触发(假设第一次现在有效,因为我目前正在修复另一个错误),之后再次执行 SP 时会触发该错误。因此,似乎无论SolrNet.Startup.Init<ActiveProduct>("http://192.168.2.190:8983/solr");在做什么(创建某种与我认为与容器有关的会话)当从 SP 调用时它都没有释放“会话”,因此第二次(以及之后的每次)SP 被执行,错误被触发。有没有办法停止会话或从容器中释放。作为解决方法,我可以做的是try - catch部分SolrNet.Startup.Init,但这并不干净。

谢谢。

4

1 回答 1

0

I'll try to summarize the steps / requirements with explanations whenever possible:

  • For some reason SQL Server seems to trigger the "hidden" dependencies of the merged SolrNet. Usually you can just use the merged SolrNet (which includes all integration modules) and if you ignore the integration classes the dependencies won't trigger. But in this case the unmerged SolrNet is necessary.
  • SolrNet does HTTP requests to the Solr server, so the DLL must be registered with UNSAFE permissions in SQL-CLR.
  • SolrNet Initialization (Startup.Init) must happen only once per application, but you don't have a 'root' context in SQL-CLR to place this initialization. A workaround is to use a singleton or a Lazy type. SQL-CLR doesn't run .NET 4 yet, but you can backport the Lazy type or use FSharp.Core.dll's implementation (I blogged about this some time ago)
于 2012-01-23T16:31:32.540 回答