0

我希望能夠在優化以下數據檢索方面獲得一些幫助。這是用例。我想在Telerik ASP.NET MVC網格中顯示一個翻譯者(供應商)列表。這些翻譯人員通過語言對來定價(或定價方案)。這個數據庫中有400個譯員。我想最初顯示所有內容,但讓用戶通過他們翻譯的語言進行過濾。有一個供應商(翻譯員)表,語言對錶(用於源語言和目標語言的FK)和語言表。將EF Linq優化爲ASP.NET MVC Telerik Grid的實體查詢

這是我的,但它很慢。主要原因是,對於每個供應商,我需要獲得他們翻譯的每一種獨特語言(源語言和目標語言)。沒有ForEach,我不知道該怎麼做。我甚至不知道如何在沒有一段時間的SQL,臨時表或遊標的情況下執行此操作。

public List<tblSupplier> GetApprovedSuppliers() 
{ 
    var query = from s in db.tblSuppliers 
       join c in db.tblCountryLists on s.SupplierCountry equals c.CountryID into g1 
       from c in g1.DefaultIfEmpty() 
       select new 
       { 
        SupplierID = s.SupplierID, 
        SupplierName = s.CompanyName == null ? s.SupplierFirstName + " " + s.SupplierLastName : s.CompanyName, 
        SupplierEmails = s.SupplierEmails, 
        SupplierType = s.SupplierType, 
        Country = c.Countryname 
       }; 

    List<tblSupplier> list = query.ToList().ConvertAll(s => new tblSupplier 
    { 
     SupplierID = s.SupplierID, 
     SupplierName = s.SupplierName, 
     SupplierEmails = s.SupplierEmails, 
     SupplierType = s.SupplierType, 
     Country = s.Country 
    }).OrderBy(s => s.SupplierName).ToList(); 

    list.ForEach(s => s.Languages = this.GetLanguages(s.SupplierID)); 

    return list; 
} 

public string GetLanguages(int supplierID) 
{ 
    var query = (from ps in db.tblSupplierPricingSchemes 
        join lp in db.tblLangPairs on ps.PSLangPairID equals lp.ProductID 
        join sl in db.tblLanguages on lp.SourceLanguageID equals sl.LanguageID 
        where ps.SupplierID == supplierID 
        select sl.LanguageDesc) 
       .Union 
       (from ps in db.tblSupplierPricingSchemes 
        join lp in db.tblLangPairs on ps.PSLangPairID equals lp.ProductID 
        join tl in db.tblLanguages on lp.TargetLanguageID equals tl.LanguageID 
        where ps.SupplierID == supplierID 
        select tl.LanguageDesc);   

    return string.Join(", ", query); 
} 

任何幫助表示讚賞。

謝謝你,史蒂夫

回答

1

您必須減少查詢數量。如果您已正確定義模型,則可以使用「包括」開始。如果您沒有正確定義具有導航屬性的模型,則可以將多個GetLanguages調用替換爲單個調用,並在您的應用程序中重建數據集。要更換GetLanguages的多次調用更改消息簽名:

public Dictionary<id, string> GetLanguages(int[] suppplierIds) 

與supplierIds.Contains(ps.SupplierID)取代ps.SupplierID == supplierID' - 你需要至少EFv4,使這項工作。所以結果應該是這樣的:

public Dictionary<id, string> GetLanguages(int[] supplierIds) 
{ 
    var query = (from ps in db.tblSupplierPricingSchemes 
        join lp in db.tblLangPairs on ps.PSLangPairID equals lp.ProductID 
        join sl in db.tblLanguages on lp.SourceLanguageID equals sl.LanguageID 
        where ps.SupplierID == supplierID 
        select new { ps.SupplierID, sl.LanguageDesc }) 
       .Union 
       (from ps in db.tblSupplierPricingSchemes 
        join lp in db.tblLangPairs on ps.PSLangPairID equals lp.ProductID 
        join tl in db.tblLanguages on lp.TargetLanguageID equals tl.LanguageID 
        where ps.SupplierID == supplierID 
        select new { ps.SupplierID, tl.LanguageDesc }); 

    query = from x in query 
      group x by x.SupplierID into g 
      select g; 

    return query.ToDictionary(x => x.Key, x => String.Join(", ", x)); 
} 

不,你必須只使用此方法,如:

Dictionary<int, string> languages = GetLanguages(list.Select(s => s.SupplierID)); 
list.ForEach(s => s.Languages = languages[s.SupplierID]); 
+0

這看起來很棒拉吉斯拉夫!我今天下午晚些時候會嘗試這個。謝謝! – SteveB