在LINQ to SQL类中,为什么从实现EntitySet
的外键IEnumerable
对象创建的属性,DataContext
上的对象Table
为{{ 1}}实现IQueryable
的对象?
编辑:为了澄清,这是一个示例,说明了我想要了解的内容。这个例子:
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#级别而不是在数据库中完成的。
我知道发生这种情况的原因是IQueryable
和IEnumerable
之间的差异,为什么第一个示例中的MatchPlayers
对象不实现IQueryable
接口获得与后一个示例相同的好处。
答案 0 :(得分:3)
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?”,你可以。
答案 1 :(得分:1)
表实际上是一个概念问题 - 它们确实存在于服务器上,因此您需要查询以获取条目。外键条目是由另一个查询实际获取的条目,因此此时它们在本地可用。这是一个相当粗略的描述,但希望它能克服一般概念。
答案 2 :(得分:0)
这是addressed on the MSDN forums。推理的要点是在对数据库进行查询时跟踪添加和删除的对象非常困难。相反,EntitySet是您可以操作的相关对象的本地副本。不幸的是,正如您所注意到的,这会产生将表达式转换为LINQ to Objects调用而不是表现更好的LINQ to SQL的副作用。