Linq-to-SQL在一个Linq-to-SQL语句中左连接/多个左连接左连接

时间:2013-06-17 10:45:09

标签: linq linq-to-sql stored-procedures left-join

我正在尝试将SQL过程重写为Linq,只要它适用于小型数据集,它一切顺利并且工作正常。我无法在任何地方找到答案。事实是,我在查询中有3个连接,2个是left joins,1个是inner join,它们都相互连接/像树一样。您可以在下面看到SQL过程:

SELECT ...
    FROM sprawa s (NOLOCK) 
        LEFT JOIN strona st (NOLOCK) on s.ident = st.id_sprawy
        INNER JOIN stan_szczegoly ss (NOLOCK) on s.kod_stanu = ss.kod_stanu
        LEFT JOIN broni b (NOLOCK) on b.id_strony = st.ident

我想问你的是将其翻译成Linq的方法。现在我有这个:

var queryOne = from s in db.sprawa
               join st in db.strona on s.ident equals st.id_sprawy into tmp1
               from st2 in tmp1.DefaultIfEmpty()
               join ss in db.stan_szczegoly on s.kod_stanu equals ss.kod_stanu
               join b in db.broni on st2.ident equals b.id_strony into tmp2
               from b2 in tmp2.DefaultIfEmpty()
               select new { };

似乎没问题,但是当使用SQL事件探查器检查时,发送到数据库的查询看起来像这样:

SELECT ... FROM    [dbo].[sprawa] AS [Extent1] 
           LEFT OUTER JOIN [dbo].[strona] AS [Extent2] 
                ON [Extent1].[ident] = [Extent2].[id_sprawy]    
           INNER JOIN [dbo].[stan_szczegoly] AS [Extent3] 
                ON [Extent1].[kod_stanu] = [Extent3].[kod_stanu]    
           INNER JOIN [dbo].[broni] AS [Extent4] 
                ON ([Extent2].[ident] = [Extent4].[id_strony]) OR 
                (([Extent2].[ident] IS NULL) AND ([Extent4].[id_strony] IS NULL))

正如您所看到的,两个SQL查询都有所不同。效果是相同的,但后者的工作速度无比慢(不到一秒到超过30分钟)。还有一个union,但不应该是问题。如果要求我将粘贴代码。

对于如何改进我的Linq语句的性能或如何以正确翻译的方式编写它的任何建议,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

我想我找到了解决方案:

var queryOne = from s in db.sprawa
               join st in db.strona on s.ident equals st.id_sprawy into tmp1
               where tmp1.Any()
               from st2 in tmp1.DefaultIfEmpty()
               join ss in db.stan_szczegoly on s.kod_stanu equals ss.kod_stanu
               join b in db.broni on st2.ident equals b.id_strony into tmp2
               where tmp2.Any()
               from b2 in tmp2.DefaultIfEmpty()
               select new { };

换句话说,在每个where table.Any()语句后into table。它不会使翻译变得更好,但是将执行时间从近30分钟(!)加速到大约5秒。

但必须小心使用,因为它可能导致在结果集中丢失一些记录。