SolrNet в CLR хранимая процедура - PullRequest
0 голосов
/ 13 января 2012

Кто-нибудь когда-нибудь использовал Solrnet внутри хранимых процедур CLR? Я был бы очень признателен за ссылки на некоторые хорошие учебники.

Одна проблема, с которой я сталкиваюсь, заключается в том, что я не могу найти способ включить библиотеку SolrNet в качестве ссылки на проект базы данных VS (2008) (SQL Server).

Обновление:

Таким образом, кажется, что когда у вас есть проект SQL Server, и вы хотите добавить ссылку на библиотеку, он должен сначала существовать в самом SQL Server, что имеет смысл. Это делается путем создания сборки в SQL Server из самой DLL со следующим SQL:

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 (которая была в папке .Net Windows), однако Я не могу найти требуемую версию 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:

Мне удалось зарегистрировать все необходимые библиотеки (некоторые из которых я получил из источника SolrNet на GitHub ). Итак, теперь SolrNet зарегистрирован как сборка в SQL Server, и поэтому я могу ссылаться на него из .NET SQL Server Project (для создания хранимой процедуры 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

CLRStoredProcedures2 - это имя проекта .NET SQL Server и пространство имен по умолчанию в VS 2008

ActiveProduct - это имя документа в Solr, а класс cs с аннотациями Solr

Как видно из вывода, первый Pipe.send("Hellooo") выполняет свою работу, поэтому SP работает нормально до тех пор.

Когда я искал вышеупомянутую ошибку, я обнаружил, что она покажет, когда каждый дважды пытается зарегистрировать экземпляр Solr в одном приложении. Теперь я не вижу, где я регистрирую экземпляр дважды. Я что-то здесь упускаю?

Обратите внимание, что вышеуказанная функция cs работала нормально, когда выполнялась в консольном приложении cs, разработанном на моей машине. Другая важная деталь заключается в том, что сервер SOLR размещается на моем компьютере, который находится в той же сети, что и мой SQL Server 2005.

Обновление 4:

Для начала, ошибка, о которой я упоминал выше (в обновлении 3), не срабатывает, когда SP запускается 1-й раз сразу после развертывания (предположим, что 1-й раз работает сейчас, так как у меня есть другая ошибка, которая у меня сейчас есть)работает над исправлением), ошибка возникает при повторном запуске SP.Таким образом, кажется, что что бы SolrNet.Startup.Init<ActiveProduct>("http://192.168.2.190:8983/solr"); ни делал (создавая какую-то сессию, связанную с контейнером, я думаю), при вызове из SP он не освобождает «сессию», поэтому во 2-й раз (и каждый раз после)SP выполнен, ошибка сработала.Есть ли способ как-то остановить сеанс или выпустить из контейнера.То, что я могу сделать в качестве обходного пути, это try - catch часть SolrNet.Startup.Init, однако это не чисто.

Спасибо.

1 Ответ

0 голосов
/ 23 января 2012

Я постараюсь обобщить шаги / требования с объяснениями, когда это возможно:

  • По какой-то причине SQL Server, похоже, вызывает "скрытые" зависимости объединенной SolrNet. Обычно вы можете просто использовать объединенную SolrNet (которая включает в себя все модули интеграции), и если вы игнорируете классы интеграции, зависимости не сработают. Но в этом случае необходим необрешенный SolrNet.
  • SolrNet выполняет HTTP-запросы к серверу Solr, поэтому DLL должна быть зарегистрирована с разрешениями UNSAFE в SQL-CLR.
  • Инициализация SolrNet (Startup.Init) должна происходить только один раз для каждого приложения, но у вас нет корневого контекста в SQL-CLR для размещения этой инициализации. Обходной путь должен использовать одиночный или Ленивый тип . SQL-CLR еще не запускает .NET 4, но вы можете создать бэкпорт типа Lazy или использовать реализацию FSharp.Core.dll (я писал об этом некоторое время назад)
...