使用带编译查询的UnitOfWork模式

时间:2013-09-11 18:38:47

标签: c# linq-to-sql unit-of-work linq.compiledquery

我正在尝试在我的项目中设置一些使用工作单元设计模式的编译查询。这些查询在某些请求期间会多次重复使用,并使它们编译查询有助于加快应用程序的速度。我注意到的一件事是我必须传入我正在使用的datacontext,而不是能够使用我在我的工作单元类中设置的存储库。

这是有效的:

        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;
            }
        }

这就是我想要的:

构造

    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;
        }

这是编译的查询(我已经将对datacontext中表的调用替换为构造函数中设置的表):

  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;
                }
            }

当我尝试使用在UnitOfWork类中设置的表时,我在编译的查询中创建了一个断点,这些表由于某种原因为null,即使它们是在创建类时设置的。是否有可能做到这一点?或者编译后的查询是否总是需要传入datacontext?

提前致谢!

1 个答案:

答案 0 :(得分:1)

简短回答:是的,你必须把它传入。

您的代码的结构方式是您提供DataContext以及执行查询的其他参数。因为你将它悬挂在静态属性之外,所以你总是必须传递DataContext,因为它不是静态的。

但即使您在非静态上下文中创建了查询,也没有适当的情况,只要查询就会创建DataContext并生存。你最终会得到一个长期存在的DataContext,这不是如何使用它并引入了很多问题。