gpt4 book ai didi

c# - NHibernate session 工厂计数限制?

转载 作者:行者123 更新时间:2023-11-30 21:37:44 44 4
gpt4 key购买 nike

我正在通过代码(不是配置文件)创建多个 session 工厂我遇到的问题是,在第 20 次 session 工厂创建之后,我开始遇到异常 (MappingException),我不知道为什么。

无论顺序如何,20 号之后就坏了。只要 session 在前 20 个中,就可以成功创建 session 。

MappingException 消息:唯一后缀 100_ 长度必须小于最多 4 个字符

感谢任何帮助。

public static void AddPortfolioToConnectionstrings(string portfolio, string 
connectionString)
{
var configuration = new Configuration()
.Configure()
.SessionFactoryName(portfolio)
.SetProperty("connection.connection_string", connectionString);

...

_portfolios.Add(portfolio, configuration.BuildSessionFactory());
}

最佳答案

像往常一样,NHibernate 的错误消息对任何人都没有帮助。

在我的例子中,我遇到了这个错误:

MappingException message: Unique suffix 100_ length must be less than maximum 4 characters

经过深入研究,此错误的原因是连接字符串的服务器地址错误,然后提供了错误的凭据。


关于您的问题:连接 20 个目标数据库很不寻常,但可以做到。在下面展示的实现中,我使用了 12 个 session 工厂,但请确保您在 64 位进程空间中运行代码,否则它会很快耗尽 32 位进程可用的内存。

您唯一需要注意的是,您需要有一个自定义 session 工厂构建器,您将其绑定(bind)为单例。我的实现的轻量级版本如下所示:

public interface ISessionFactoryBuilder
{
IDictionary<string, ISessionFactory> SessionFactories { get; }
}

public IDictionary<string, ISessionFactory> SessionFactories { get; private set; }
private readonly IConfigurationManager _configurationManager;

public SessionFactoryBuilder(IConfigurationManager configurationManager)
{
this._configurationManager = configurationManager;

this.SessionFactories = this.BuildSessionFactories();
}

private IDictionary<string, ISessionFactory> BuildSessionFactories()
{
var sessionFactories = new Dictionary<string, ISessionFactory>(StringComparer.InvariantCultureIgnoreCase);
var connectionStrings = this._configurationManager.GetConnectionStrings();

if (connectionStrings.Count == 0)
throw new ConfigurationErrorsException("No connection descriptions can be found!");

foreach (ConnectionStringSettings item in connectionStrings)
if (item.Name != "LocalSqlServer" && item.Name != "OraAspNetConString")
sessionFactories.Add(item.Name, this.InitializeSessionFactory(item.ConnectionString, item.ProviderName));

return sessionFactories;
}

private class Connectiontypes
{
public string Db_type { get; set; }
public FluentConfiguration Configuration { get; set; }
}

private ISessionFactory InitializeSessionFactory(string connectionString = "", string providerName = "")
{
Trace.WriteLine($"{connectionString}");

List<SessionFactoryBuilder.Connectiontypes> conntypes = new List<SessionFactoryBuilder.Connectiontypes> {
new SessionFactoryBuilder.Connectiontypes
{
Db_type = "System.Data.SqlClient",
Configuration = Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.ConnectionString(connectionString).ShowSql()
.Dialect<XMsSql2005Dialect>()) },
new SessionFactoryBuilder.Connectiontypes
{
Db_type = "System.Data.OracleDataClient",
Configuration = Fluently.Configure().Database(OracleDataClientConfiguration.Oracle10
.ConnectionString(connectionString).Provider<NHibernate.Connection.DriverConnectionProvider>()
.Driver<NHibernate.Driver.OracleManagedDataClientDriver>()
.Dialect<XOracle10gDialect>().ShowSql())
},
new SessionFactoryBuilder.Connectiontypes
{
Db_type = "System.Data.MySQLDataClient", Configuration = Fluently.Configure()
.Database(MySQLConfiguration.Standard.ConnectionString(connectionString).ShowSql())
}
};

FluentConfiguration fluentConfiguration = conntypes.Find(x => x.Db_type == providerName).Configuration;

fluentConfiguration.ExposeConfiguration(x =>
{
x.SetProperty("command_timeout", "120");
});

#if DEBUG
fluentConfiguration.ExposeConfiguration(x =>
{
x.SetInterceptor(new SqlStatementInterceptor());
});
#endif

var mappings = fluentConfiguration.Mappings(m =>
{
m.FluentMappings.AddFromAssemblyOf<UsersMap>();
});

var config = mappings.BuildConfiguration();

foreach (PersistentClass persistentClass in config.ClassMappings)
{
persistentClass.DynamicUpdate = true;
}

var sessionFactory = mappings
#if DEBUG
.Diagnostics(d => d.Enable(true))
.Diagnostics(d => d.OutputToConsole())
#endif
.BuildSessionFactory();

return sessionFactory;
}

public void Dispose()
{
if (this.SessionFactories.Count > 0)
{
foreach (var item in this.SessionFactories)
{

item.Value.Close();
item.Value.Dispose();
}

this.SessionFactories = null;
}
}
}

然后我将其与 NInject 绑定(bind)为:

Bind<ISessionFactoryBuilder>().To<SessionFactoryBuilder>().InSingletonScope().WithConstructorArgument("configurationManager", context => context.Kernel.Get<IConfigurationManager>());

当然,您必须在程序启动附近的任何位置执行此操作,或者我们称之为 Composition Root .

这里唯一缺少的是 IConfigurationManager 的明显实现,它只是我对 ConfigurationManager 的自定义包装器,它被传递给 SessionFactoryBuilder 的构造函数。

通过这种方式,您可以在应用程序启动时构建 session 工厂构建器,而不会再构建(显然直到应用程序域重新启动左右),因此您不会因为有那么多 SessionFactories 闲逛和获取而出现内存泄漏或 OutOfMemory 异常已创建。

关于c# - NHibernate session 工厂计数限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46938003/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com