Оптимизация EF Linq для запросов сущностей для ASP.NET MVC Telerik Grid - PullRequest
0 голосов
/ 21 ноября 2011

Я надеялся, что смогу получить некоторую помощь в оптимизации следующего поиска данных. Вот пример использования. Я хочу отобразить список переводчиков (поставщиков) в сетке Telerik ASP.NET MVC. Эти переводчики имеют тарифы (или схемы ценообразования) по языковым парам. В этой базе данных менее 400 переводчиков. Сначала я хочу отобразить их все, но пусть пользователи фильтруют по языкам, которые они переводят. Существует таблица поставщика (переводчика), таблица языковых пар (с FK для исходного и целевого языка) и таблица языков.

Вот что у меня есть, но медленно. Основная причина заключается в том, что для каждого поставщика мне нужно получить каждый уникальный язык, который они переводят (исходный и целевой языки). Я не знаю, как это сделать без 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 Ответ

1 голос
/ 21 ноября 2011

Вы должны уменьшить количество запросов. Если вы правильно определили модель, вы можете начать с помощью Включить. Если у вас нет правильно определенной модели со свойствами навигации, вы можете заменить несколько вызовов GetLanguages на один вызов и восстановить набор данных в своем приложении. Чтобы заменить несколько вызовов GetLanguages, измените подпись сообщения на:

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

и замените ps.SupplierID == supplierID на supplierIds.Contains (ps.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]);
...