2017-04-19 25 views
3

我需要僅從醫院表HospitalId和Name中選擇兩列。 我試了下面的代碼,它選擇了從醫院表中導致性能下降的所有列。請幫我選擇醫院的表只有兩列LINQ:如何使用IQueryable()選擇特定列()

public HttpResponseMessage GetAvailableHospitalsByAjax(System.Guid? DirectorateOfHealthID = null, System.Guid? UnitTypeID = null, string DeviceTypeIDs = null) 
{ 
    Context db = new Context(); 
    var query = db.Hospitals.AsQueryable(); 
    if (UnitTypeID != null) 
    { 
     query = query.Where(j => j.HospitalDepartments.Any(www => www.Units.Any(u => u.UnitTypeID == UnitTypeID))); 
    } 

    if (DirectorateOfHealthID != null) 
    { 
     query = query.Where(h => h.DirectorateHealthID == DirectorateOfHealthID); 
    } 


    query = query.Where(j => j.HospitalDepartments.Any(u => u.Units.Any(d => d.Devices.Any(s => s.Status == Enums.DeviceStatus.Free))) 
    && j.HospitalDepartments.Any(hd => hd.Units.Any(u => u.Beds.Any(b => b.Status == Enums.BedStatus.Free)))); 



    var list = query.ToList().Select(w => new HospitalInfo() 
    { 
     Id = w.ID, 
     Name = w.Name 

    }).ToList(); 


    return Request.CreateResponse(HttpStatusCode.OK, list); 
} 

回答

1

投影之前取出ToList電話:

var list = query.Select(w => new HospitalInfo() 
    { 
    Id = w.ID, 
    Name = w.Name 

    }).ToList(); 

隨着該ToList叫你物化查詢之前做投影

0

因爲你做query.ToList()這實現了整個查詢與所有列到內存中。這實際上是一個不好的習慣。相反,刪除它,無論如何你已經擁有了它。該Select投影你有只檢索相關列,但:

var list = query.Select(w => new HospitalInfo() 
{ 
    Id = w.ID, 
    Name = w.Name 

}).ToList(); 
1

IQueryable<T>執行與所有過濾器在服務器端選擇查詢。因此,工作量減少,速度變快。

IEnumerable<T>在服務器端執行select查詢,在客戶端加載內存中的數據,然後過濾數據。因此做更多的工作,並變得緩慢。

List<T>只是一種輸出格式,雖然它實現了IEnumerable<T>,但與查詢沒有直接關係。

所以,

var list = query.ToList().Select(w => new HospitalInfo() 
    { 
     Id = w.ID, 
     Name = w.Name 

    }).ToList(); 

在你的代碼使用query.ToList()。這意味着首先它將所有數據拉入內存,然後應用Select查詢。如果要檢索HospitalID和Name,然後刪除ToList(),那麼您的代碼就像

var list = query.Select(w => new HospitalInfo 
     { 
      Id = w.ID, 
      Name = w.Name  
     }).ToList();