2

well this is my very very first project with fluent hibernate.i've had small experience in hibernate and nhibernate.

This context is completely new to me since this is a web app project. So i have my webapp project with most of the fluent nhibernate found on the net. so i have This entities:

namespace myproject.model
{
  public class Request
  {
    public virtual string Id { get; private set; }
    public virtual Route route { get; set; }
    public virtual int code { get; set; }

  }
}

namespace myproject.model
{
  public class Route
  {
    public virtual string Id { get; private set; }
    public virtual string client_id { get; set; }
    public virtual IList<Request> requests { get; set; }

    public Route()
    {
        requests = new List<Request>();
    }

  }

}

//Mapping are like this.will only post one
namespace myproject.mappings
{
 public class RequestMap : ClassMap<Request>
 {
    public RequestMap()
    {
        Id(x => x.Id);
        Map(x => x.short_code);
        References(x => x.route);
    }
  }
}

//NhibernateSessionPerRequest
namespace myproject.Boostrap
{
  public class NhibernateSessionPerRequest : IHttpModule
  {
    private static readonly ISessionFactory _sessionFactory;

    static NhibernateSessionPerRequest()
    {
        _sessionFactory = CreateSessionFactory();
    }

    //all others IHttpModule event and methods are here
    private static ISessionFactory CreateSessionFactory()
    {

        FluentConfiguration configuration = Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.
                                                                              ConnectionString(x => x.FromConnectionStringWithKey("localdb")))
            .Mappings(m => {
                            m.FluentMappings.AddFromAssemblyOf<myproject.model.Request>();
                            m.FluentMappings.AddFromAssemblyOf<myproject.model.Route>();
                           }
                     ).ExposeConfiguration((c)=> savedConfig = c);;

        return configuration.BuildSessionFactory();
    }

  }

   private static Configuration savedConfig;

    public static void BuildSchema(NHibernate.Cfg.Configuration config)
    {
        new SchemaExport(config).Create(false, true);
    }

    public static void BuildSchema(ISession session)
    {
        var export = new SchemaExport(savedConfig);
        export.Execute(false,true,false,session.Connection,null);
    }


}

I've added the module in webconfig

  <add name="NhibernateSessionPerRequest" type="myproject.Boostrap.NhibernateSessionPerRequest"/>

in order to test the generation of the tables i've added a test project (class library) added ref to nunit.framework 2.8.5 and myproject.

namespace myproject.Tests
{
  [TestFixture]
  public class CanGenerateSchemaTestSuite
  {
    [Test]
    public void CanGenarateSchema()
    {
       NhibernateSessionPerRequest.BuildSchema(NhibernateSessionPerRequest.GetCurrentSession());

     }
  }
}

the test method always fails, and i'm having this exception:

CanGenerateSchemaTestSuite (1 test), 1 test failed: Child test failed CanGenarateSchema, Failed: System.TypeInitializationException

so how testing is being done in an asp.net context?? thanks for reading this.thanks

black sensei
  • 6,528
  • 22
  • 109
  • 188

2 Answers2

7

Just a vague comment on the other solution; you don't need to delete database files completely for this; just drop the tables:

.ExposeConfiguration(SetupTestDatabase)

...

private static void SetupTestDatabase(NHibernate.Cfg.Configuration config)
{
    var schema = new SchemaExport(config);
    schema.Drop(true, true);
    schema.Create(true, true);
}

It just means you can run your tests on a different database without changing anything else.

Edit; woops; thought that was an accepted solution. If you're doing it in a test, just do it like this:

   [Test]
    public void Test_can_store_and_get_objects()
    {
        var factory = CreateSessionFactory();
        using (var s = factory.OpenSession())
        { 
             ...
        }
    }

    private static ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure().Database(SQLiteConfiguration.Standard.UsingFile("firstProject.db"))
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Address>()) // <-- Refer to parent project
        .ExposeConfiguration(SetupTestDatabase)
        .BuildSessionFactory();
    }
Doug
  • 32,844
  • 38
  • 166
  • 222
5

Here is an example of mine. You need to use ExposeConfiguration and pass a method which accepts a configuration and you just build the database there and then using SchemaExport:

class SqliteRefSessionFactoryProvider : ISessionFactoryProvider
{

    public const string SqliteRefFileName = "ref.db";

    public ISessionFactory GetSessionFactory()
    {
        return Fluently.Configure().Database(
            SQLiteConfiguration.Standard.UsingFile(SqliteRefFileName).ShowSql())
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SsoToken>())
            .ExposeConfiguration(BuildSchema)
            .BuildSessionFactory();
    }

    private static void BuildSchema(NHibernate.Cfg.Configuration configuration) 
    {
        if (File.Exists(SqliteRefFileName))
            File.Delete(SqliteRefFileName);

        new SchemaExport(configuration)
          .Create(false, true);
    }
}
Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • oh that was really kind of you.I've seen the trick.but one more concern remains.For the look of if.I'll have to to that in my `NhibernateSessionPerRequest` class and `BuildSchem`a would be made private.So how do i run the `BuildSchema` method, even further how do i run it in my `test project`? thanks – black sensei Nov 17 '10 at 12:34
  • As you can see, I have my own ISessionFactoryProvider which is DI-ed into the session factory singleton. For unit test, I use a test one which does the build as well. Is that what you meant by the question? – Aliostad Nov 17 '10 at 13:04
  • Hello i'm not using any kind of Dependency Injection librairy, my issue here is not to be able to figure out how to test this in a separate project(meaning my testproject), i've updated the title of this post and added new approaches that i got from your answer.Please let me know if i'm going it wrong.thanks for your time – black sensei Nov 17 '10 at 14:03