c# - 更高效的 Linq to SQL

标签 c# sql linq linq-to-sql

我一直在尝试使用 Linq to SQL 来帮助我搜索一个简单的数据库。 DB由两个表组成,Player和Team,每个玩家记录都有一个Team Id来链接两个表(Player.TeamId -> Team.Id)。

为了增加一点复杂性,Team 表包含过去 10 个赛季的历史数据。这意味着每个团队最多可以有 10 个不同的记录 团队表,与所代表的 10 个赛季有关。

我想要我的查询做的是搜索一个球员,该球员返回符合搜索条件的球员列表和该球队那个赛季每个返回球员的队友列表。

搜索条件包括名字、姓氏、(列表)季节和团队名称。

我的查询是这样的:

using (var context = DataContextFactory.Context)
{
var playerList = context.GetTable<Player>(t =>  searchRequest.Seasons.Contains((int) t.Team.Season))
                              .Where(p => string.Equals(p.Surname, (searchRequest.Surname ?? p.Surname), StringComparison.OrdinalIgnoreCase) &&
                                          string.Equals(p.Forename, (searchRequest.Forename ?? p.Forename), StringComparison.OrdinalIgnoreCase) &&
                                          string.Equals(p.Team.Name, (searchRequest.TeamName ?? p.Team.Name), StringComparison.OrdinalIgnoreCase)
                                    )).ToList();

var teamMateList = new List<Player>();

foreach (var Player in playerList.Select(p => context.GetTable<Player>(
                              tm => tm.Team.Id == p.Team.Id && tm.Id.CompareTo(p.Id) != 0)))
{
    otherPeopleList.AddRange(people);
}
}

这有效,将返回符合搜索条件的球员列表 (playerList),对于每个球员,我可以从第二个查询结果 (teamMateList) 中映射他们的队友。

我的问题是 Linq to SQL 将其转换为非常低效的 SQL。 第一个问题是它从数据库中选择了整个 Player 表——我假设这是因为 Linq to SQL 无法将我的 Where 子句转换为标准 SQL,因此返回整个表并在代码中执行查询的 Where 部分?

第二个问题是,在执行第二个查询时,Linq to SQL 会为 playerList 的每个成员生成对 DB 的单独查询。在阅读代码时,这可能是有道理的,但我认为 Linq 会足够聪明,可以将其转换为单个查询,从而提高搜索效率。

关于如何简化我的查询有什么想法/建议吗?

最佳答案

I assume this is because Linq to SQL can't translate my Where clauses to standard SQL and so returns the entire table and does the Where part of the query in code?

或者,换句话说 - 因为您编写的条件忽略了 LINQ 可以转换的任何合理方法。

string.Equals(p.Surname, (searchRequest.Surname ?? p.Surname

如果 searchRequest.Surname 为空,则不要选择。

var query = context.GetTable<Player>(*first condition);

if (!string.IsNullOrEmpty(searchRequest.Surname) {
query = query.Where (x=> x.surname.StartsWIth (searchRequest.Surname);
}

没有人说您必须在一次运行中定义整个 LINQ 部分。这在编写手动 SQL 时很糟糕,在 LINQ 中也很糟糕。一个 LINQ 表达式,其结果再次是一个 IQueryable 并明确支持这样的链接。我们对数亿行执行高效的 LINQ,它看起来很棒 - 但只是因为我们没有像您那样糟糕地编写代码。

您的第二个问题是相同的 - 您通过强制 LINQ 使用低效的搜索模式从错误的一面攻击问题。使用分组进行选择,然后将客户端与另一个表连接。

关于c# - 更高效的 Linq to SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9174816/

相关文章:

c# - 为什么下面的电话是模棱两可的?

c# - 在 LinQ Lambda Join 中检索索引

MySQL 匹配模式并选择数字和字母

java - 简单但复杂的 HQL/SQL 查询

c# - 是否可以使用 LINQ(对实体)执行此 T-SQL 查询

c# - 将对象转换为可查询对象

c# - 如何在asp.net中访问同一类的其他方法中的页面加载方法

c# - 在 XAML 中访问类变量

sql - 无法在 SQL Server 中找到百分比

c# - 如何从谓词对象中删除重复项?