【问题标题】:EntitySet vs Table query performance in LINQ2SQLLINQ2SQL 中的 EntitySet 与表查询性能
【发布时间】:2008-10-14 11:16:03
【问题描述】:

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

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

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

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

我知道发生这种情况的原因是IQueryables 和IEnumerables 之间的区别,那么为什么第一个示例中的MatchPlayers 对象没有实现IQueryable 接口以获得与后一个例子。

【问题讨论】:

    标签: linq linq-to-sql ienumerable iqueryable


    【解决方案1】:
    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?”,你可以。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        这是addressed on the MSDN forums。推理的要点是,在对数据库进行查询时,很难跟踪添加和删除的对象。相反,EntitySet 是您可以操作的相关对象的本地副本。不幸的是,正如您所注意到的,这具有将表达式转移到 LINQ to Objects 调用而不是性能更好的 LINQ to SQL 的副作用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-06
          • 2017-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-03
          • 2011-06-09
          • 2011-06-09
          相关资源
          最近更新 更多