views:

191

answers:

2

My scenario:

This is an ASP.NET 4.0 web app programmed via C#

I implement a repository pattern. My repositorys all share the same ObjectContext, which is stored in httpContext.Items. Each repository creates a new ObjectSet of type E. Heres some code from my repository:

public class Repository<E> : IRepository<E>, IDisposable
    where E : class
{
    private DataModelContainer _context = ContextHelper<DataModelContainer>.GetCurrentContext();
    private IObjectSet<E> _objectSet;
    private IObjectSet<E> objectSet
    {
        get
        {
            if (_objectSet == null)
            {
                _objectSet = this._context.CreateObjectSet<E>();
            }
            return _objectSet;
        }
    }

    public IQueryable<E> GetQuery()
    {
        return objectSet;
    }

Lets say I have 2 repositorys, 1 for states and 1 for countrys and want to create a linq query against both. Note that I use POCO classes with the entity framework. State and Country are 2 of these POCO classes.

Repository stateRepo = new Repository<State>();
Repository countryRepo = new Repository<Country>();

IEnumerable<State> states = (from s in _stateRepo.GetQuery()
                             join c in _countryRepo.GetQuery() on s.countryID equals c.countryID
                             select s).ToList();
Debug.WriteLine(states.First().Country.country)

essentially, I want to retrieve the state and the related country entity. The query only returns the state data... and I get a null argument exception on the Debug.WriteLine

LazyLoading is disabled in my .edmx... thats the way I want it.

+1  A: 

Your repository implementation is very similar to mine, especially the way you are storing the ObjectContext. It works fine for me, so I don't think it's a conceptual problem.

Try using a static objectcontext (no wrapper) just to see if that fixes the problem. Perhaps there is a bug in your ContextHelper which causes your context to get disposed and recreated.

Adrian Grigore
I Debug.WriteLine everytime a new ObjectContext is created and am positive its working correctly. Is lazy loading enabled in your project?
Chris Klepeis
@Chris Klepeis: Yes, it is.
Adrian Grigore
@Adrian: We disabled it because our application is n layer and do not want other layers to be able to run queries in that fashion
Chris Klepeis
@Chris Klepeis: Sorry, I missed that bit.
Adrian Grigore
+1  A: 

You're doing a join without retrieving anything from it. There are multiple solutions to your problem:

  • Use Include to load the dependent entities: from s in ((ObjectSet<State>) _stateRepo.GetQuery).Include("Country"). The problem with this approach is that you should expose the ObjectSet directly rather than as a IQueryable if you want to avoid casting.
  • Use context.LoadProperty(states.First(), s => s.Country) to explicitly load the Country from the database for a given state.
  • Select both entities in the query: from s in ... join c ... select new { s, c }. You won't be able to access directly the state's Country property but you have it in the anonymous type.
  • Enable lazy loading.
Julien Lebosquain
I'm doing something similar to http://stackoverflow.com/questions/542595/entity-framework-singletonish-objectcontext-good-bad-or-overthinking for my ObjectContext.
Chris Klepeis
According to http://www.4guysfromrolla.com/articles/060904-1.aspx, HttpContext.Items works on a per-request basis. Therefore different requests should not cause race conditions with the object context.
Adrian Grigore
You're right for HttpContext.Items. Removed that part from my answer, thank you.
Julien Lebosquain