Linq to SQL string concatenation where子句生成buggy sql

时间:2011-06-08 10:01:49

标签: linq entity-framework-4.1

类似问题的答案对我不起作用。

考虑这个字符串concat查询:

.Where(c => (
              c.FirstName ?? String.Empty +
              c.LastName ?? String.Empty +
              c.CompanyName ?? String.Empty).Contains(searchText)

导致下面的sql。由于第一个案例陈述,这实际上无法在姓氏上找到匹配。

我正在跳过各种各样的箍来寻找解决方案(计算列<忘记它,udf<忘记它,sp<忘记它),在哪里主题变化......

CASE 
            WHEN ([Extent3].[FIRST_NM] IS NULL) 
                THEN 
                    CASE 
                        WHEN (@p__linq__0 + [Extent3].[LAST_NM] IS NULL) 
                            THEN 
                                CASE 
                                    WHEN (@p__linq__1 + [Extent3].[COMPANY_NM] IS NULL) 
                                        THEN @p__linq__2 
                                ELSE @p__linq__1 + [Extent3].[COMPANY_NM] 
                                END 
                    ELSE @p__linq__0 + [Extent3].[LAST_NM] 
                    END 
        ELSE [Extent3].[FIRST_NM] 
        END LIKE @p__linq__3 ESCAPE N''~'')

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

查看生成的SQL,看起来您可能需要引入更多包围:

.Where(c => (
          (c.FirstName ?? String.Empty) +
          (c.LastName ?? String.Empty) +
          (c.CompanyName ?? String.Empty)).Contains(searchText)

因为看起来??的优先级低于+(至少在生成的SQL中)

(不幸的是我在网上找到的唯一C#运算符优先级规范是.NET 1.1/2003,但是在后面的规范中看来,空值合并运算符看起来就在条件上面了

答案 1 :(得分:0)

知道了。但这是Fugly(sql也是如此)。 String concat需要一些认真的关注!

.Where(c => (
              ((c.FirstName ?? String.Empty).Length > 0 && (c.FirstName ?? String.Empty).Contains(searchText)) ||
               ((c.LastName ?? String.Empty).Length > 0 && (c.LastName ?? String.Empty).Contains(searchText)) ||
                ((c.CompanyName ?? String.Empty).Length > 0 && (c.CompanyName ?? String.Empty).Contains(searchText))
                )  
              )

产量

AND (((( CAST(LEN(CASE WHEN ([Extent3].[FIRST_NM] IS NULL) THEN @p__linq__0 ELSE [Extent3].[FIRST_NM] END) AS int)) > 0) 
        AND (CASE WHEN ([Extent3].[FIRST_NM] IS NULL) THEN @p__linq__1 ELSE [Extent3].[FIRST_NM] END LIKE @p__linq__2 ESCAPE N''~'')) 
        OR ((( CAST(LEN(CASE WHEN ([Extent3].[LAST_NM] IS NULL) THEN @p__linq__3 ELSE [Extent3].[LAST_NM] END) AS int)) > 0) 
        AND (CASE WHEN ([Extent3].[LAST_NM] IS NULL) THEN @p__linq__4 ELSE [Extent3].[LAST_NM] END LIKE @p__linq__5 ESCAPE N''~'')) 
        OR ((( CAST(LEN(CASE WHEN ([Extent3].[COMPANY_NM] IS NULL) 
        THEN @p__linq__6 ELSE [Extent3].[COMPANY_NM] END) AS int)) > 0) 
        AND (CASE WHEN ([Extent3].[COMPANY_NM] IS NULL) THEN @p__linq__7 ELSE [Extent3].[COMPANY_NM] END LIKE @p__linq__8 ESCAPE N''~'')))