2

I am using NHibernate to connect to my database and retreive some data as follows:

public abstract class BaseContext<TContext> : IBaseContext<TContext> where TContext : IGuid
{
    #region Data Members

    // NHibernate session
    private readonly Lazy<ISession> _session;

    // Logger
    private static readonly ILog log = LogManager.GetLogger(typeof(BaseContext<TContext>));

    #endregion

    #region Ctor

    protected BaseContext()
    {

        // Initialize session 
        _session = new Lazy<ISession>(NHibernateHelper.OpenSession);
        // log
        log.Debug("Session has been created but has not yet been used.");
    }

    #endregion

    #region Propreties

    /// <summary>
    /// Lazy load a session with NHibernate
    /// </summary>
    public ISession Session
    {
        get { return _session.Value; }
    }

    #endregion

    #region Methods

    /// <summary>
    /// Retreives all object of type <see cref="TContext"/> from the database.
    /// </summary>
    /// <returns>A list of all the <see cref="TContext"/> items</returns>
    public IEnumerable<TContext> Get()
    {
        try
        {
            log.DebugFormat("Retrieving all items of type {0} from the database.",
                    typeof(TContext).Name);

            // Return all the items of TContext type
            return from item in Session.Query<TContext>()
                   select item;
        }
        catch (Exception ex)
        {
            log.Error("Could not retreive items from the database.", ex);
            return default(IEnumerable<TContext>); 
        }
    }

    /// <summary>
    /// Disposes the context
    /// </summary>
    public void Dispose()
    {
        // Dispose session
        Session.Dispose();
    }

    #endregion
}

I have a wrapper class that represent each entity I want to retreive, such as :

public class EntityContext : BaseContext<DataEntity>
{
    #region Methods

    /// <summary>
    /// Gets a list of all enitities
    /// </summary>
    /// <returns>A list of all entities</returns>
    public new IEnumerable<DataEntity> Get()
    {
        return base.Get();
    }

    #endregion
}

To expose this, I created a WCF Service that uses it:

    public List<DataEntity> Get()
    {
        using (EntityContext context = new EntityContext())
        {
            var entities = context.Get();
            return entities.ToList();
        }
    }

When I was consuming the WCF Service, I kept getting 'Connection aborted' exception, until i figured out the cause. when I remove the using statement (the call for the Dispose method) it works fine.

My question is why? and how should I implement this correctly?

Thanks, Omri

Omri Btian
  • 6,499
  • 4
  • 39
  • 65
  • I can see how this problem could occur if you `return entities;`. But are you sure you have this problem even when you `return entities.ToList();`? – Eren Ersönmez Aug 17 '13 at 11:15
  • @ErenErsönmez yes that is exatcly what i don't understand ... – Omri Btian Aug 17 '13 at 11:27
  • ToList() will just force load of your *root* entities, but not their lazy properties. These are loaded later, when firstly accessed (lazy load). at that moment the Session is disposed... no lazy. That's why you need a "request lasting" session – Radim Köhler Aug 17 '13 at 12:27
  • @RadimKöhler you are right, I made all my mappings not lazy load just to check if it works, and it does. so now my question is, how to create a 'request lasting' session? the examples in your answer use IOC containers which i don't want to use. do you have an example without one? – Omri Btian Aug 17 '13 at 13:22
  • You are right... I've extended answer with some links. *The IoC is something which you should start to think about anyhow* ;) But, the WcfOperationSessionContext is there out of the box! – Radim Köhler Aug 17 '13 at 13:46

1 Answers1

1

What you need is the Session lifetime, which will be related to the request of the WCF Service. And this is what you should google for.

Here are some links, how to:

The request lasting session:

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335