Search code examples
c#nhibernatefluent-nhibernate

NHibernate Cannot attach the MDF


I am trying to attach to a SQL Server Express LocalDB with NHibernate but I keep on getting the exception:

An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

With the inner exception being:

Cannot attach the file 'Test.mdf' as database 'Test'.

I have encountered this error before when using Entity Framework and could fix it through:

> sqllocaldb stop v11.0
> sqllocaldb delete v11.0

However that is not working in this instance. Below is my complete program:

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Mapping;
using NHibernate.Tool.hbm2ddl;

namespace Sandbox
{
    public class Person
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }

    public class PersonMap : ClassMap<Person>
    {
        public PersonMap()
        {
            Id(p => p.Id);
            Map(p => p.Name);
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var connectionString =
                @"Data Source=(LocalDB)\v11.0;AttachDBFilename=Test.mdf;" +
                @"Initial Catalog=Test;Integrated Security=True";

            var _sessionFactory = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2012.ConnectionString(connectionString))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>())
                .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true))
                .BuildSessionFactory();
        }
    }
}

Solution

  • The issue was, unlike Entity Framework, NHibernate won't create the database for you. I had to first do the following to create the database:

            var databaseName = "Test";
            var databaseFile = "Test.mdf";
    
            if(!File.Exists(databaseFile))
            {
                var connectionString = @"Data Source=(LocalDB)\v11.0;Integrated Security=True;";
                var query = $@"
                    CREATE DATABASE {databaseName} ON PRIMARY (
                        NAME = '{databaseName}',
                        FILENAME = '{databaseFile}');";
    
                using(var connection = new SqlConnection(connectionString))
                {
                    using(var command = new SqlCommand(query, connection))
                    {
                        connection.Open();
                        command.ExecuteNonQuery();
                    }
                }
    
                Console.WriteLine("Created database!");
            }
    

    NB: This isn't production quality code, just a demonstration of the problem.