优化 ASP.NET MVC Telerik 网格的 EF Linq to Entities 查询

发布于 2024-12-17 06:37:56 字数 2191 浏览 3 评论 0原文

我希望我能得到一些帮助来优化以下数据检索。这是用例。我想在 Telerik ASP.NET MVC 网格中显示翻译者(供应商)列表。这些翻译器按语言对提供费率(或定价方案)。该数据库中的译者数量不到 400 名。我想一开始就显示所有这些内容,但让用户按他们翻译的语言进行过滤。有供应商(翻译者)表、语言对表(源语言和目标语言为 FK)和语言表。

这是我所拥有的,但速度很慢。主要原因是对于每个供应商,我需要获取他们翻译的每种独特语言(源语言和目标语言)。如果没有 ForEach,我不知道如何做到这一点。我什至不确定如何在没有 while、临时表或游标的情况下在 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);
}

任何帮助表示赞赏。

谢谢, 史蒂夫

I was hoping I could get some help optimizing the following data retrieval. Here is the use case. I want to display a list of translators (suppliers) in a Telerik ASP.NET MVC grid. These translators have rates (or pricing schemes) by language pair. There are less 400 translators in this database. I want to display all of them initially, but let users filter by languages they translate. There is a supplier (translator) table, language pair table (with FK for source and target language), and language table.

Here is what I have but it is slow. The primary reason is that for each supplier, I need to get every unique language they translate (source and target language). I don't know how to do that without a ForEach. I'm not even sure how I could do this in SQL without a while, temp table, or a cursor.

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);
}

Any help is appreciated.

Thanks,
Steve

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独陪着我 2024-12-24 06:37:56

您必须减少查询数量。如果您已正确定义模型,则可以从使用 Include 开始。如果您没有正确定义具有导航属性的模型,您可以将 GetLanguages 的多个调用替换为单个调用并在应用程序中重建数据集。要替换 GetLanguages 的多个调用,请将消息签名更改为:

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

并将 ps.SupplierID == sellerID 替换为 sellerIds.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]);

You must reduce number of queries. If you have correctly defined model you can start by using Include. If you don't have correctly defined model with navigation properties you can replace multiple calls of GetLanguages to single call and reconstruct dataset in your application. To replace multiple calls of GetLanguages change message signature to:

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

and replace ps.SupplierID == supplierID with supplierIds.Contains(ps.SupplierID)` - you need at least EFv4 to make this work. So the result should look like:

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));
}

No you must only use this method like:

Dictionary<int, string> languages = GetLanguages(list.Select(s => s.SupplierID));
list.ForEach(s => s.Languages = languages[s.SupplierID]);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文