views:

27

answers:

1

Good evening people,

I have been using Fluent Nhibernate for a while, I've never really dug too deep into its functionality or the many ways it can be configured. In every project I have used it in I have configure it as follows:

        if (nhConfig == null)
        {
            nhConfig = new NHibernate.Cfg.Configuration();
            nhConfig.Properties.Add(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, typeof(NHibernate.ByteCode.LinFu.ProxyFactoryFactory).AssemblyQualifiedName);

                                                                              // This obviously changes depending on what im trying to connect to
    nhConfig.Properties.Add(NHibernate.Cfg.Environment.ConnectionDriver, typeof(NHibernate.Driver.SqlServerCeDriver).AssemblyQualifiedName);

                                                                              // Configuration is simply an implementation
                                                                              // of an IConfiguration interface 
            nhConfig.Properties.Add(NHibernate.Cfg.Environment.ConnectionString, configuration.ConnectionString);


                                // In this instance, this resolves to
                                    // "NHibernate.Dialect.MsSqlCeDialect"
            nhConfig.Properties.Add(NHibernate.Cfg.Environment.Dialect, configuration.Dialect.AssemblyQualifiedName);
            nhConfig.Properties.Add(NHibernate.Cfg.Environment.ShowSql, "true");

            _sessionFactory = Fluently.Configure(nhConfig)
                                   .Mappings(m => m.FluentMappings.AddFromAssembly(configuration.MappingAssembly))
                                   .ExposeConfiguration(x => new SchemaUpdate(x).Execute(false, true))
                                   .BuildSessionFactory();
        }

Apologies for the poorly formatted code block...I can never figure out how to edit the code once you paste it in without de-activating the code tags.

So as I say, in all of my other projects, this configuration code has worked fine. The database has always been a SQLExpress database (2005 || 2008) and should the table not exist in the database for the specified entity, then it is automatically created.

However, this time an SQL Compact database is required. I have created this database simply by adding a new Database item to my assembly (TestingDB.sdf) and have actually created a "Customer" table.

Now I have the following unit test:

[Test]
    public void Function_CanCreateDomainObject()
    {
        // Create a fake entity that is mapped
        Customer fakeCustomer = new Customer();
        fakeCustomer.Name = "Function_CanCreateDomainObject";
        fakeCustomer.Birthday = DateTime.Now;

        // Get a DAO for communication
        IBaseDAO<Customer> customerDao = Container.RequestForType <IBaseDAO<Customer>>();

        // Persist the domiain object
        customerDao.Create(fakeCustomer);

        // Retrieve it in a new instance
        Customer retrievedCustomer = customerDao.Read(fakeCustomer.Id);

        // Compare values for equality
        Assert.That(retrievedCustomer.Id.Equals(fakeCustomer.Id),
            "Retrieved entity with Name: " + retrievedCustomer.Name + "(" + retrievedCustomer.Id + ")" +
            "does not match with original entity with Name: " + fakeCustomer.Name + "(" + fakeCustomer.Id + ")");
    }

Regardless of the poorly designed 'unit test' the test falls over with the following error:

ERROR [TestRunnerThread] SchemaUpdate [(null)]- could not complete schema update 
       System.NotSupportedException: Specified method is not supported.

Yes, I have all the required assemblies from the SQL Compact folder on my C:\ and in fact here is the strange part, in trying to find the source of this error, I of course debugged the unit test and stepped through the procedure line-by-line. On two occasions, the test has passed and the 'fakeCustomer' entity is persisted correctly in my database, however, 99% of the time, it will fail with the aforementioned error. The test has passed both when stepping through the test line-by-line and when simply running it from the Nunit GUI.

So, it seems like NHibernate can not imply the table structure of a SQL Compact database on its own, which is strange because I am using the ClassMap technique of FNHibernate and you'd think this would be sufficient enough to imply a table schema....every time the test is run.

Any help of guidance greatly appreciated. Thank you for your time.

A: 

Ok sorry, it was silly of me to ask such a question and not post a stack trace. Sadly, because I have just started this project, I am only able to run my code via unit test, as a result I feel the info given from Nunit about test failures is not quite as good as a stack trace.

From the Nunit GUI 'Text Output' window

***** SolutionName.Testing.DataAccess.Unit.Testing_BaseDAO.Create_CanCreateBaseDAO

21:34:32,929 ERROR [TestRunnerThread] SchemaUpdate [(null)]- could not complete schema update System.NotSupportedException: Specified method is not supported.

at System.Data.Common.DbConnection.GetSchema(String collectionName, String[] restrictionValues)

at NHibernate.Dialect.Schema.AbstractDataBaseSchema.GetTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)

at NHibernate.Tool.hbm2ddl.DatabaseMetadata.GetTableMetadata(String name, String schema, String catalog, Boolean isQuoted)

From the Nunit GUI 'errors and failures' window

at SolutionName.DataAccess.ConnectionProviders.NHibernateConnection.get_Session() in  SolutionFolder.SolutionName.DataAccess\ConnectionProviders\NHibernateConnection.cs:line 25

at SolutionName.DataAccess.ConnectionProviders.NHibernateConnection.Create[TEntity](TEntity objectToCreate) in SolutionFolder\SolutionName.DataAccess\ConnectionProviders\NHibernateConnection.cs:line 91 at SolutionFolder\SolutionName.DataAccess.BaseDAO`1.Create(T objectToCreate) in SolutionFolder\SolutionName.DataAccess\BaseDAO.cs:line 31 at SolutionName.Testing.DataAccess.Unit.Testing_BaseDAO.Function_CanCreateDomainObject() in SolutionFolder\SolutionName.Testing\DataAccess\Unit\Testing_BaseDAO.cs:line 46

at NHibernate.Cfg.Configuration.GenerateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata at NHibernate.Tool.hbm2ddl.SchemaUpdate.Execute(Action`1 scriptAction, Boolean doUpdate)