加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 更高效的Linq to SQL

发布时间:2020-12-15 21:30:17 所属栏目:百科 来源:网络整理
导读:我一直在玩 Linq to SQL来帮助我搜索一个简单的数据库. 数据库由两个表组成,即Player和Team,每个玩家记录都有一个Team Id来链接两个表(Player.TeamId – Team.Id). 为了增加一点复杂性,Team表包含过去10个赛季的历史数据.这意味着每个团队最多可以有10个不同
我一直在玩 Linq to SQL来帮助我搜索一个简单的数据库.
数据库由两个表组成,即Player和Team,每个玩家记录都有一个Team Id来链接两个表(Player.TeamId – > Team.Id).

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

我希望我的查询要做的是搜索一个播放器,该播放器返回符合搜索条件的玩家列表,以及该团队每个返回玩家的队友列表.

搜索条件包括Forname,Surname,(列表)季节和团队名称.

我的查询如下所示:

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为null,则不要选择.

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使用低效的搜索模式从错误的方面解决问题.使用group by进行选择,然后将客户端与另一个表连接.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读