Search code examples
linq-to-sqlarchitectureinversion-of-controldatacontextprefetch

Prefetching data in with Linq-to-SQL, IOC and Repository pattern


using Linq-to-SQL I'd like to prefetch some data.

1) the common solution is to deal with DataLoadOptions, but in my architecture it won't work because :

  • the options have to be set before the first query
  • I'm using IOC, so I don't directly instanciate the DataContext (I cannot execute code at instanciation)
  • my DataContext is persistent for the duration of a web request

2) I have seen another possibility based on loading the data and its childs in a method, then returning only the data (so the child is already loaded) see an example here

Nonetheless, in my architecture, it cannot not work :

  • My queries are cascaded out of my repository and can be consumed by many services that will add clauses
  • I work with interfaces, the concrete instances of the linq-to-sql objects do not leave the repositories (yes, you can work with interfaces AND add clauses)
  • My repositories are generic

Yes, this architecture is quiet complicated, but it's very cool as I can play with the code like lego ;)

My question is : what are the other possibilities to prefetch a data ?


Solution

  • In my app i use perhaps a variation to your potential solution #2. It's somewhat difficult to explain but simply: i chain and defer lazy loading in my model with custom lazy classes so as to abstract away from the LinqToSql-specific Differed Execution that i take advantage of with IQueryable. Benefits:

    • My Domain Model and Service layer upwards does not necessarily have to depend on the LinqToSql provider (i can swap out my DAL with interfaces if i want to)
    • My Service methods can and do return complete object graphs with multiple 'anchor points' for lazy loading using classes that abstract away a particular lazy loading implementation - so i can use LinqToSql-specific Differed Execution or something else (eg. anon delegates. again, refer to this answer)
    • I can maintain IQueryable results throughout my app (even to the UI if i want to) thus allowing infinite LINQ query chaining without having to worry about performance.