LINQ2SQL中EntitySet与Table的查询性能



在LINQ to SQL类中,为什么从实现IEnumerable的外键EntitySet对象创建的属性,其中DataContext上的对象是实现IQueryableTable对象?

编辑:为了澄清,这里有一个例子说明了我试图理解的内容。这个例子:

ctx.Matches.Where(x => x.MatchID == 1).Single()
           .MatchPlayers.Max(x => x.Score);

两次命中数据库作为:

ctx.MatchPlayers.Where(x => x.MatchID == 1)
                .Max(x => x.Score);

仅运行1个查询。以下是痕迹:

exec sp_executesql N'SELECT [t0].[MatchID], [t0].[Date]
FROM [dbo].[Matches] AS [t0]
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1
go
exec sp_executesql N'SELECT [t0].[MatchID], [t0].[PlayerID], [t0].[Score]
FROM [dbo].[MatchPlayers] AS [t0]
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1
go

exec sp_executesql N'SELECT MAX([t0].[Score]) AS [value]
FROM [dbo].[MatchPlayers] AS [t0]
WHERE [t0].[MatchID] = @p0',N'@p0 int',@p0=1
go

这也表明,更糟糕的是,max是在C#级别而不是在数据库中完成的。

我知道发生这种情况的原因是IQueryables和IEnumerables之间的差异,那么为什么第一个示例中的MatchPlayers对象不实现IQueryable接口以获得与后一个示例相同的好处呢。

ctx.Matches.Where(x => x.MatchID == 1).Single()

Single()返回Match,而不是IQueryable(Match)。

只需将Single()推到最后一步:

ctx.Matches
  .Where(m => m.MatchID == 1)
  .Select(m => m.MatchPlayers.Max(mp => mp.Score))
  .Single();

这个查询显示,在查询中使用MatchPlayers属性是可以的。这解决了我对提问者问题的解释——"为什么我不能在查询中使用EntitySet?",你可以。

表实际上是一个概念问题——它们确实存在于服务器上,因此您需要查询以获取条目。外键条目实际上是由另一个查询获取的,因此在这一点上它们是本地可用的。这是一个相当模糊的描述,但希望它能超越一般概念。

这在MSDN论坛上得到了解决。推理的要点是,在对数据库进行查询时,很难跟踪添加和删除的对象。相反,EntitySet是可以操作的相关对象的本地副本。不幸的是,正如您所注意到的,这会产生副作用,将表达式转换为LINQ到对象调用,而不是更好地执行LINQ到SQL。

相关内容

  • 没有找到相关文章

最新更新