AdoTransaction - isolationlevel is null asp.net mvc 5 fluent nhibernate

1.2k Views Asked by At

I have a problem with save more than one items to database in c# asp.net with fluent nhibernate. I have :

   public static readonly ISessionFactory SessionFactory = DbContext.SessionFactory();
    public static readonly ISession Session = SessionFactory.OpenSession();
    public static readonly ITransaction Transaction = Session.BeginTransaction();

    public IEnumerable<Candidate> Candidates => Session.Query<Candidate>();

    public Candidate GetUser(int id)
    {
        return Session.Query<Candidate>().FirstOrDefault(x => x.Id == id);
    }

    public void AddCandidate(Candidate candidate)
    {
        try
        {
            Session.Save(candidate);
            Transaction.Commit();
        }
        catch (Exception exception)
        {
            throw;
        }

    }

And the error is : IsolationLevel = '((NHibernate.Transaction.AdoTransaction)Transaction).IsolationLevel' threw an exception of type 'System.NullReferenceException'

More information : can't access the deleted object

My Class DbContext:

 public static class DbContext
{
    private static ISessionFactory _sessionFactory;

    static DbContext()
    {
        GetFactory();
    }
    public static void GetFactory()
    {
        var myEntities = new[]
        {
            typeof (ApplicationUser)
        };
        var configuration = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2012.ConnectionString(c => c.FromConnectionStringWithKey("ConnectionString"))
                    .ShowSql())
                .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
                .ExposeConfiguration(x =>
                {
                    x.SetProperty("", "");
                    x.AddDeserializedMapping(MappingHelper.GetIdentityMappings(myEntities), null);
                })
                .ExposeConfiguration(BuildSchema);

        _sessionFactory = configuration.BuildSessionFactory();

    }
    public static ISessionFactory SessionFactory()
    {
        return _sessionFactory;
    }

    public static ISession GetSession()
    {
        if (!CurrentSessionContext.HasBind(_sessionFactory))
            CurrentSessionContext.Bind(_sessionFactory.OpenSession());

        return _sessionFactory.GetCurrentSession();
    }
    public static ISession MakeSession()
    {
        return _sessionFactory.OpenSession();
    }
    //public static IUserStore<ApplicationUser, string> Users => new IdentityStore(MakeSession());

    private static void BuildSchema(Configuration config)
    {
        new SchemaUpdate(config)
            .Execute(true, true);
    }

}

Please, help! Thanks!

1

There are 1 best solutions below

1
On BEST ANSWER

SessionFactory should be singleton and using it as static can be part of the solution. Objects from ISession and ITransaction should be created when necessary. Try change your code to something like this:

public static readonly ISessionFactory SessionFactory = DbContext.SessionFactory();

public Candidate GetUser(int id)
{
    Candidate candidate = null;
    using (var session = SessionFactory.OpenSession())
    {
        candidate = Session.Query<Candidate>().FirstOrDefault(x => x.Id == id);
    }
    return candidate;        
}

public void AddCandidate(Candidate candidate)
{
    using (var session = SessionFactory.OpenSession())
    {
        using (var transaction = session.BeginTransaction())
        {
            try
            {
                Session.Save(candidate);
                transaction.Commit();
            }
            catch 
            {
                transaction.RollBack();
                throw;
            }
        }
    }
}

Avoid to expose Queryable as your code is doing on the Candidates property.

There are some approaches to rightly implement the session management on an application and depending whant environment code is executed it can change.

I recommend you to see these posts: http://benfoster.io/blog/yet-another-session-per-request-post

How to implement session-per-request pattern in asp.net mvc with Nhibernate