2012-01-31 49 views
0

我有這樣的LINQ查詢(如果它的正確不知道),但我要的是:的LINQ - 優化/糾正我的查詢

把我的所有公司的辦事處(即涉及到我的公司如companyid == mycompanyid ) 已宣佈他們有郵政編碼「cv」,只返回辦公室。 (代碼清晰)

var offices = from office in _readOnlySession.All<Office>() 
.GetMyOffices(_userSession) //filter out my offices using extension method 
let postcodes = _readOnlySession.All<OfficePostCode>().Where(x => x.OfficeID == office.OfficeID) 
       .Join(_readOnlySession.All<PostCodeDistrict>().Where(r=> r.Region.ToLower().StartsWith("cv".ToLower())), 
          x => x.PostCodeID, 
          y => y.PostCodeID, 
          (x, y) => new { Region = y.Region }) 
where postcodes.Any() 
select new { office.OfficeID, office.Name }; 

問題:我怎樣才能使這一切的查詢方法,更優化/正確的查詢方法?

注:「CV」將是傳遞給方法的變量 - 還挺硬編碼來說明我的例子

更新:

IQueryable<T> All<T>() where T : class, new(); 

    public IQueryable<T> All<T>() where T : class, new() 
    { 
     return GetTable<T>().AsQueryable(); 
    } 
+0

不。所有採取Func鍵作爲參數,並返回一個布爾值,而不是一個枚舉?它看起來不像代碼會編譯。 – Bodrick 2012-01-31 12:06:06

+0

@博德里克 - 它編譯和工作! – Haroon 2012-01-31 12:06:55

+0

我想你在那裏使用一些擴展方法。什麼類型是_readOnlySession?是否。所有()只返回給定類型集合中的所有對象? – Bodrick 2012-01-31 12:11:09

回答

0

這似乎是確定。只有什麼都還不能更好地工作,是主查詢之前執行讓利郵政編碼部分,而不OfficeID條件,然後用它在主查詢,如:

where postcodes.Any(pc => pc.OfficeID == office.OfficeID) 
1

我認爲OfficePostCodeOffice都有PostCodeID性質,您可能需要更改最後的.Where()子句以適應您的屬性。這應該做你想要的東西,而IMO更容易閱讀。

public IEnumerable<Office> GetOffices (string postCode) 
{ 
    List<Office> myOffices = _readOnlySession.All<Office>() 
     .GetMyOffices (_userSession) 
     .ToList(); // Get all the offices you are interested in. 


    List<OfficePostCode> postCodeDistricts = _readOnlySession 
     .All<OfficePostCode>() 
     .Where (x => x.Region.StartsWith (postCode, true, System.Globalization.CultureInfo.InvariantCulture)) 
     .ToList(); // A list of OfficePostCodes with the specified region. 

    // Using the 3 parameter overload for StartsWith lets you specify a case invariant comparison, 
    // which saves you from having to do .ToLower(). 

    return myOffices.Where (o => postCodeDistricts.Any (pcd => o.PostCodeID == pcd.PostCodeID)); 
} 

當然,你可以通過刪除中間變量來壓縮它,但我個人覺得這樣更清晰。它也使調試更容易,因爲您可以將中斷變量放在斷點上。

+0

如果有效,它看起來更有效率。沒有創建匿名對象,並且會消除連接。 Plus更具可讀性。 – weston 2012-01-31 16:12:39

0

也許這樣的事情?

var offices = _readOnlySession.All<Office>() 
    .GetMyOffices(_userSession) //filter out my offices using extension method 
    .Where(office => office.PostCodes.Any(pc => pc.District.Region.ToUpperInvariant().StartsWith("CV")));