实体框架渴望加载不起作用

时间:2016-08-23 12:04:51

标签: c# entity-framework entity-framework-6 eager-loading

我想使用Entity Framework 6和Eager加载从db加载对象列表。但实体框架使用延迟加载。我使用了SQL分析器,当访问引用子实体的属性时执行查询。 通过使用“包含”,您可以一次性加载相关实体,但它不会发生。我的代码如下:

    using (var flightsPricingRulesContext = new FlightsPricingRulesDbContext())
    {
       flightsPricingRulesContext.Configuration.ValidateOnSaveEnabled = false;
       flightsPricingRulesContext.Configuration.AutoDetectChangesEnabled = false;


   var filter = PredicateBuilder.True<FlightsPricingRulesDataAccess.Models.ServiceFee>();

    if (!String.IsNullOrEmpty(selectedMarketId))
    {
       var selectedMarket = Int32.Parse(selectedMarketId);
       filter = filter.And(sf => sf.MarketId == selectedMarket);
    }

    if (!String.IsNullOrEmpty(selectedApplicationTypeId))
    {
       var selectedAppplicationType = Int32.Parse(selectedApplicationTypeId);
       filter = filter.And(sf => sf.ApplicationType == selectedAppplicationType);
    }

    var Query = 
    from P in flightsPricingRulesContext.ServiceFee.AsExpandable().Where(filter)select P;

    switch (orderby)
    {
      case null:
      case "":
      case "Id":
      Query = String.IsNullOrEmpty(orderbydirection) || orderbydirection  == "ASC"
      ?Query.OrderBy(p => p.Id): Query.OrderByDescending(p => p.Id);
      break;

      case "market":
      Query = String.IsNullOrEmpty(orderbydirection) || orderbydirection == "ASC"
      ? Query.OrderBy(p => p.MarketId)
      : Query.OrderByDescending(p => p.MarketId);
      break;
    }

    var takeitems = 10 ;
    var skipitems = (Int32.Parse(page) - 1) * 10);

    //BY USING INCLUDE EAGER LOADING IS ENABLED
    Query = Query.Skip(skipitems).Take(takeitems).
    Include(sf => sf.ServiceFeeZone.Select(sfz => sfz.Zone)).
    Include(sf => sf.ServiceFeeCarrier).
    Include(sf => sf.ServiceFeeClassOfService).
    Include(sf => sf.ServiceFeeDate).
    Include(sf => sf.ServiceFeeMarkUpAssignment).
    Include(sf => sf.ServiceFeeAssignment);

    var results = Query.ToList();//HERE A COMPLETE QUERY SHOULD BE 
    //SENT TO THE DB FOR RETRIEVING ENTITES INCLUDING THEIR CHILDREN

    var totalresults = flightsPricingRulesContext.ServiceFee.AsExpandable().Count(filter);

    var pagedservicefees = new PagedServiceFee();
    pagedservicefees.totalitems = totalresults.ToString();
    pagedservicefees.servicefees = new List<FlightsPricingRules.Models.ServiceFee>();


    foreach (var servicefeedto in results)
    {
       var servicefee = new FlightsPricingRules.Models.ServiceFee();

       servicefee.id = servicefeedto.Id.ToString();
       servicefee.marketId = servicefeedto.MarketId.ToString();
        //.....
        //SOME MORE PROPERTIES
        //                      

    //CHILD ENTITIES

        //Zones
        servicefee.zones = new List<Zone>();
        //HERE AN   ADDITIONAL QUERY IS MADE TO LOAD THE CHILD ENTITIES-WHY?
        foreach (var zonedto in servicefeedto.ServiceFeeZone)
        {
           var zone = new Zone();
           zone.id = zonedto.ZoneId.ToString();
           zone.name = zonedto.Zone.Name;
           servicefee.zones.Add(zone);
         }

          //Carriers
          servicefee.carriers = new List<Carr>();
          //ALSO HERE AND ADDITIONAL QUERY IS MADE
          foreach (var carrierdto in servicefeedto.ServiceFeeCarrier)
          {
            var carrier = new Carr();
            carrier.id = carrierdto.AirlineId.ToString();
            servicefee.carriers.Add(carrier);
           }


      pagedservicefees.servicefees.Add(servicefee);
   }
   //.......
   //SOME MORE CHILD ENTITIES
   //


return Json(pagedservicefees, JsonRequestBehavior.DenyGet);

}                

1 个答案:

答案 0 :(得分:2)

好的,我明白了。事实证明,放置Include语句的位置确实很重要。我将Include语句放在.AsExpandable()之前,并在父实体之后放置,现在执行急切加载。我还可以使用SQL分析器验证,查询包含所有必要的连接,并且它的执行速度非常快。正确的查询现在是:

var Query = from P in flightsPricingRulesContext.ServiceFee
.Include(sf =>   sf.ServiceFeeCarrier)
.Include(sf=>sf.ServiceFeeAssignment)
.Include(sf => sf.ServiceFeeClassOfService)
.Include(sf => sf.ServiceFeeDate)
.Include(sf => sf.ServiceFeeMarkUpAssignment)
.Include(sf => sf.ServiceFeeZone.Select(zo => zo.Zone))
.AsExpandable().Where(filter) select P;

发布答案以防有人遇到相同的情况。