0

这个问题根本不需要时间来执行,但如果我取消最后一行的注释,则需要 5 秒。这怎么会对查询产生如此大的影响?这几乎是完全相同的查询。

return db.Parties.Where(predicate).Select(p => new SearchResult
{
    adressPerson = p.Contacts.SingleOrDefault(m => m.contact_type == "H").streetname,
    //adressOrg = p.Contacts.SingleOrDefault(m => m.contact_type == "W").streetname
});  

如何定位问题?

这是谓词的样子:

    predicate = predicate.Or(p => p.surname.EndsWith(keyword));
    predicate = predicate.Or(p => p.lastname.EndsWith(keyword));
    predicate = predicate.Or(p => p.organisation.EndsWith(keyword));
    predicate = predicate.Or(p => p.Contacts.Any(c => c.streetname.EndsWith(keyword)));
    predicate = predicate.Or(p => p.Memberships.Any(m => m.Congregation.congregation_name.EndsWith(keyword)));
    predicate = predicate.Or(p => p.PartyCategories.Any(m => m.Category.category_name.EndsWith(keyword) || m.Category.category_code.EndsWith(keyword)));  

我知道发布大量代码很愚蠢,但无论如何这里是 SQL 查询。有什么线索吗?

SELECT (
    SELECT [t6].[streetname]
    FROM [dbo].[Contact] AS [t6]
    WHERE ([t6].[contact_type] = @p7) AND ([t6].[party_id] = [t0].[party_id])
    ) AS [adressPerson], (
    //SELECT [t7].[streetname]
    //FROM [dbo].[Contact] AS [t7]
    //WHERE ([t7].[contact_type] = @p8) AND ([t7].[party_id] = [t0].[party_id])
    //) AS [adressOrg]
FROM [dbo].[Party] AS [t0]
WHERE ([t0].[surname] LIKE @p0) OR ([t0].[lastname] LIKE @p1) OR ([t0].[organisation] LIKE @p2) OR (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Contact] AS [t1]
    WHERE ([t1].[streetname] LIKE @p3) AND ([t1].[party_id] = [t0].[party_id])
    )) OR (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Membership] AS [t2]
    LEFT OUTER JOIN [dbo].[Congregation] AS [t3] ON [t3].[congregation_id] = [t2].[congregation_id]
    WHERE ([t3].[congregation_name] LIKE @p4) AND ([t2].[party_id] = [t0].[party_id])
    )) OR (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[PartyCategories] AS [t4]
    INNER JOIN [dbo].[Category] AS [t5] ON [t5].[category_id] = [t4].[category_id]
    WHERE (([t5].[category_name] LIKE @p5) OR ([t5].[category_code] LIKE @p6)) AND ([t4].[party_id] = [t0].[party_id])
))

已解决 原来最后一个 select 语句中的 INNER JOIN 不起作用。所以我将谓词的最后一行更改为:

predicate = predicate.Or(p => p.PartyCategories
    .GroupJoin(db.Categories, b => b.category_id, c => c.category_id, (b, c) => new { b, c })
    .SelectMany(c => c.c.DefaultIfEmpty(), (c, b) => new { c.c, b })
    .Any(m => m.b.category_name.EndsWith(keyword) || m.b.category_code.EndsWith(keyword)));
4

2 回答 2

2

如何定位问题?

与往常一样,找出问题的方法是查看生成的 SQL,并通过 SQL 分析器运行它。

我的猜测是,当您只对单个联系人类型感兴趣时,它会从简单的内部连接变为更复杂的东西,甚至可能是“N+1-selects”问题。无论如何,查看 SQL 应该会使其更加清晰。

于 2011-09-12T08:43:27.980 回答
0

尼克拉斯,

我会按照建议查看 SQL,以了解该级别发生了什么。我还建议.Include()对初始 linq 查询进行一次,因为这会急切地加载Contacts, Memberships and PartyCategories实体。否则,您肯定会延迟加载 N+1 选择模式。查看以下链接以了解 .included 的用法:

http://blogs.msdn.com/b/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx

Linq-to-entities - Include() 方法未加载

http://www.singingeels.com/Articles/Entity_Framework_and_Lazy_Loading.aspx

干杯...

于 2011-09-12T09:28:02.097 回答