I am trying to set up some compiled queries in my project which uses a unit of work design pattern. These queries get reused multiple times during certain requests and making them compiled queries helps a lot in speeding up the application. One thing I noticed is that I have to pass in the datacontext that I am using instead of being able to use the repositories I have set up in my Unit of Work class.
Here is what works:
private static Func<PivotalDataContext, Binary, Binary, Int32?, IQueryable<Location>> GetLocationFunc
{
get
{
Func<PivotalDataContext, Binary, Binary, Int32?, IQueryable<Location>> func =
CompiledQuery.Compile(
(PivotalDataContext db, Binary destCityId, Binary stateId, Int32? cityNeoId) =>
(
(from cityDest in db.Destination_Cities
where
cityDest.Destination_City_Id == destCityId || cityDest.Neo_Id == cityNeoId
join destCountry in db.Destination_Countries
on cityDest.Destination_Country_Id equals destCountry.Destination_Country_Id into country
from destCountry in country.DefaultIfEmpty()
join destCont in db.Destination_Continents
on destCountry.Destination_Continent_Id equals destCont.Destination_Continent_Id into continent
from destCont in continent.DefaultIfEmpty()
select new Location
{
CityName = destCity.Name,
CountryName = destCountry.Name,
ContinentName = destContinent.Name
})));
return func;
}
}
Here is what I want:
Constructor:
private static IRepository<Destination_Country> _destCountryRepo;
private static IRepository<Destination_Continent> _destContinentRepo;
private static IRepository<Destination_City> _destinationCityRepo;
public LocationService()
{
_destCountryRepo = UnitOfWork.DestCountryRepo;
_destCityRepo = UnitOfWork.DestCityRepo;
_destContinentRepo = UnitOfWork.DestContinentRepo;
_destCountryRepo = UnitOfWork.DestCountryRepo;
}
Here is the compiled query (I have replaced the calls to the tables from the datacontext to the tables set up in the constructor):
private static Func<PivotalDataContext, Binary, Binary, Int32?, IQueryable<Location>> GetLocationFunc
{
get
{
Func<PivotalDataContext, Binary, Binary, Int32?, IQueryable<Location>> func =
CompiledQuery.Compile(
(PivotalDataContext db, Binary destCityId, Binary stateId, Int32? cityNeoId) =>
(
(from cityDest in _destCityRepo.Table
where
cityDest.Destination_City_Id == _destCityId || cityDest.Neo_Id == cityNeoId
join destCountry in _destCountryRepo.Table
on cityDest.Destination_Country_Id equals destCountry.Destination_Country_Id into country
from destCountry in country.DefaultIfEmpty()
join destCont in _destContinentRepo.Table
on destCountry.Destination_Continent_Id equals destCont.Destination_Continent_Id into continent
from destCont in continent.DefaultIfEmpty()
select new Location
{
CityName = destCity.Name,
CountryName = destCountry.Name,
ContinentName = destContinent.Name
})));
return func;
}
}
When I try using the tables set up in the UnitOfWork class and I create a breakpoint at the compiled query those tables are for some reason null, even though they are set when the class is created. Is it possible to do this? Or does the compiled query always need a datacontext passed in?
Thanks in advance!