NHibernate: Создание ConnectionProvider, который динамически выбирает, к какой из нескольких баз данных подключаться?

У меня есть проект, который подключается ко многим базам данных SQL Server. Все они имеют одинаковую схему, но разные данные. Данные по существу отделены от клиента. Когда в приложение asp.net поступает запрос, он может сказать, какая база данных необходима, и устанавливает сеанс.

Сейчас мы создаем новую SessionFactory для каждой базы данных клиентов. Некоторое время это работало хорошо, но с большим количеством клиентов мы создаем больше баз данных. Мы начинаем сталкиваться с проблемами памяти, потому что каждая фабрика имеет свой собственный QueryPlanCache.Я написал пост о моей отладке памяти.

Я хочу сделать так, чтобы у нас был один SessionFactory, который использует ConnectionProvider, чтобы открыть соединение с нужной базой данных. То, что у меня до сих пор выглядит примерно так:

public class DatabaseSpecificConnectionProvider : DriverConnectionProvider
{
    public override IDbConnection GetConnection()
    {
        if (!ThreadConnectionString.HasValue)
            return base.GetConnection();

        var connection = Driver.CreateConnection();
        try
        {
            connection.ConnectionString = ThreadConnectionString.Value;
            connection.Open();
        }
        catch(DbException)
        {
            connection.Dispose();
            throw;
        }
        return connection;
    }
}

Это прекрасно работает, если для обработки запроса требуется только одна база данных, поскольку я могу установить строку подключения в локальной переменной потока во время инициализации. Когда я сталкиваюсь с проблемами, я сталкиваюсь с операцией уровня администратора, которая требует доступа к нескольким базам данных.

Поскольку ConnectionProvider не знает, какой сеанс открывает соединение, он не может решить, какой использовать. Я мог бы установить локальную переменную потока перед открытием сеанса, но это имеет проблемы, так как соединения сеанса открываются лениво.

Мне также понадобится создать CacheProvider, чтобы избежать коллизий кэша. Это столкнется с подобной проблемой.

Так есть идеи? Или это просто просит слишком много от NHibernate?

Редактировать: я нашелэтот ответ, который предполагает, что мне придется положиться на какое-то глобальное состояние чего я хотел бы избежать Если у меня активно несколько сеансов, я бы хотел, чтобы ConnectionProvider отвечал соединением с соответствующей базой данных.

Изменить 2: Я склоняюсь к решению, которое создаст ConnectionProvider для сеанса по умолчанию, который всегда используется для каждого сайта. А затем для соединений с дополнительными базами данных я бы открыл соединение и передал его. Недостатки этого я вижу, что я не могу использовать кэш второго уровня на вспомогательных сессиях, и мне придется отслеживать и закрывать соединение себя.

Ответы на вопрос(1)

Ваш ответ на вопрос