Need help with my code using a base class?
I think it would be better if Session.Begin() returned an IDisposable, which would call Session.Close() in its Dispose(). That way, you can enclose the whole method inside using and you don't have to worry about calling it properly. (For example, it's not called in your code if the code is invalid.)
You can extract the creation of I or O into a generic method. It will also have a delegate parameter that represents the type-specific fill method.
It's better if you throw a specific exception (maybe something like InvalidCodeException), not Exception.


With these changes, the code would look like this:

private P CreateP&lt;T&gt;(PDetail pDetail, Action&lt;T&gt; fillT) where T : P, new()
{
    var p = new T { PDetail = pDetail };
    FillBaseP(p);
    fillT(p);
    return p;
}

public P GetP()
{
    using (this.Session.Begin())
    {
        var pDetail = GetPDetail();

        if (pDetail == null)
            return null;

        switch (pDetail.Code)
        {
        case "1":
            return CreateP&lt;I&gt;(pDetail, FillI);
        case "3":
            return CreateP&lt;O&gt;(pDetail, FillO);
        default:
            throw new InvalidCodeException("Code is invalid");
        }
    }
}



  If I'm constantly checking type like If(var is O) or If(var is I) I feel as though I'm doing something wrong. Is this the case?


Yeah, probably. But it's hard to tell (and advise a better approach) without seeing the code.