2012-04-27 60 views
2

我有这个功能的Linq-to-Sql语句。如何优化这个孩子检索linq-to-sql语句?

​​

它给了我所选的孩子ID,根据要求,但我一直在运行SQL事件探查器。

此声明似乎向每个selectedParentId的数据库发送一个单独的请求,这对我而言似乎不太合适。

有没有一种方法可以重构此声明以最小化服务器的流量?我应该采取一种不同的方法,还是这样做呢?

编辑

感谢您的指导。

这对我的跟踪输出的解释是一个错误,Linq-To-SQL对SQLServer 2005做出了完全合理的声明,就像它对SQLServer 2008一样。问题在于别处。

+0

对于selectedParentIds有什么奇怪的吗?如果你对它做一个ToList()会发生什么?例如.chere(c => selectedParentIds.ToList()。Contains(c.parentId))。 – Phil 2012-04-27 17:10:24

回答

1

对SQL 2008使用LINQ to SQL的相同查询生成单个SQL查询。你能测试SQL Server 2008吗?

例如:

IEnumerable<int> list = new List<int>{1,2,3}; 

Models.Where (m => list.Contains(m.Id)).Select (m => m.Id).ToList(); 

主要生产

-- Region Parameters 
DECLARE @p0 Int = 1 
DECLARE @p1 Int = 2 
DECLARE @p2 Int = 3 
-- EndRegion 
SELECT [t0].[Id] 
FROM [Models] AS [t0] 
WHERE [t0].[Id] IN (@p0, @p1, @p2) 

并采用实体框架同样的事情产生

SELECT 
[Extent1].[Id] AS [Id] 
FROM [dbo].[Models] AS [Extent1] 
WHERE [Extent1].[Id] IN (1,2,3) 

所以没有能够检查这对SQL 2005,我米会冒险并说,除非升级服务器,否则没有什么可以做的。

+0

是的,但我怀疑客户是否准备升级。我猜对于SQL Server 2008框架使用“表值参数”http://msdn.microsoft.com/en-us/library/bb675163.aspx – Jodrell 2012-04-27 16:53:23

+3

我不认为LINQ到SQL会根据版本产生不同的结果您正在使用的服务器。如果用“.ToString()”替换“.ToList()”,则可以在调试器中看到生成的查询。 – RobSiklos 2012-04-27 17:05:18

+0

有趣的是,2005年生成的语句都是完全有效的TSQL。 – Jodrell 2012-04-27 17:05:53

1

这是否会产生任何不同?

public IEnumerable<int> GetChildIds(IEnumerable<int> selectedParentIds) 
{ 
using (var context = new MyContext()) 
{ 
    return context.Children 
     .Where(c => selectedParentIds.Any(p => p == c.parentId)) 
     .Select(c => c.Id) 
     .ToList(); 
} 
} 
+0

我在运行时得到一个'System.NotSupportedException',消息“本地序列不能用于除Contains运算符之外的查询运算符的LINQ to SQL实现。“它是否与SQL2008 +服务器一起工作? – Jodrell 2012-04-27 17:01:52

+0

另外,它的合法的引用嵌套闭包的方式,在嵌套闭包方面似乎。似乎是有效的Linq,所以我会记住。 – Jodrell 2012-04-27 17:03:45

+0

该查询不起作用使用Linq to SQL来对付SQL 2008,但是使用Entity Framework,虽然这是一个更复杂和效率更低的查询。 – Phil 2012-04-27 17:04:47

0

如果您收到不同的输出为不同版本的SQL Server的你总是可以尝试这样的事情

public IEnumerable<int> GetChildIds(IEnumerable<int> selectedParentIds) 
{ 
    using (var context = new MyContext()) 
    { 
     var query = context.Children; 
     foreach (var id in selectedParentIds) 
     { 
      query = query.Where(q => q.parentId == id); 
     } 

     return query.Select(q => q.Id) 
        .ToList(); 
    } 
} 

我不再有SQL Server 2005中的一个实例,以测试这对(SQL即使是初始代码,使用兼容模式的Server 2008 R2仍然会生成单个查询,但是无论您使用的是哪种版本的SQL Server,这应该会生成一个包含多个where子句的单个查询。