Reputation: 292685
I'm trying to do something slightly unusual... I currently have a SQLite database, accessed with NHibernate. This database is frequently uploaded to a server. I have a new requirement to create a new table for reporting purposes, which is expected to become pretty big. This table doesn't need to be uploaded to the server, so I'd like to put it in a separate database, and use ATTACH DATABASE to access it transparently from my main database.
The problem is I don't know how to do that with NHibernate... How can I tell NHibernate to attach the other database when it connects? I can't find any connection string parameter or NH configuration property allowing to do that... is it even possible?
An acceptable option would be to manually execute the ATTACH DATABASE
command when the connection is open, but I don't know how to do that. When I build the NH session factory, it immediately tries to update the schema (hbm2ddl.auto = update
), and I don't have an opportunity to do anything with the connection before that. So it will just try to create the new table on my main database, which of course is not what I want...
Has anybody ever done that before? How did you do it?
Thanks
EDIT: In case someone needs to do the same, here's my solution, inspired by Diego's answer
Connection provider:
public class AttachedDbConnectionProvider : DriverConnectionProvider
{
private string _attachedDbAlias;
private string _attachedDbFileName;
public override IDbConnection GetConnection()
{
var connection = base.GetConnection();
if (!string.IsNullOrEmpty(_attachedDbAlias) && !string.IsNullOrEmpty(_attachedDbFileName))
{
using (var attachCommand = connection.CreateCommand())
{
attachCommand.CommandText = string.Format(
"ATTACH DATABASE '{0}' AS {1}",
_attachedDbFileName.Replace("'", "''"),
_attachedDbAlias);
attachCommand.ExecuteNonQuery();
}
}
return connection;
}
public override void Configure(IDictionary<string, string> settings)
{
base.Configure(settings);
settings.TryGetValue("connection.attached_db_alias", out _attachedDbAlias);
settings.TryGetValue("connection.attached_db_filename", out _attachedDbFileName);
}
}
Configuration file:
<property name="connection.provider">MyApp.DataAccess.AttachedDbConnectionProvider, MyApp.DataAccess</property>
<property name="connection.attached_db_alias">reportdb</property>
<property name="connection.attached_db_filename">mydatabase.report.db</property>
Now, to map a class to a table in the attached database, I just need to specify "reportdb." in the mapping file
Upvotes: 1
Views: 650
Reputation: 52745
This might help...
public class MyConnectionProvider : DriverConnectionProvider
{
public override IDbConnection GetConnection()
{
var connection = base.GetConnection();
var attachCommand = connection.CreateCommand();
attachCommand.CommandText = "ATTACH DATABASE FOO";
attachCommand.ExecuteNonQuery();
return connection;
}
}
Config:
<property name="connection.provider">MyConnectionProvider, MyAssembly</property>
Upvotes: 1