【问题标题】:Linq-To-Entities subquery with string concatenation具有字符串连接的 Linq-To-Entities 子查询
【发布时间】:2016-06-24 04:16:46
【问题描述】:

我正在尝试将我编写的 SQL 查询转换为等效的 Linq-To-Entities 查询。它有一个子查询,将几个字段连接在一起,然后用作我需要加入的字段。

SQL:

select distinct ta.Filename
from TableA ta 
inner join ( 
    SELECT distinct isnull(tb.StringField,convert(varchar,tc.IntField) + convert(varchar,tb.IntFieldB)) as NewNames
        FROM TableB tb
        inner join TableC tc
            on tb.fkC = tc.ID
        ) tj
    on tj.NewNames = ta.Filename

这是我目前的 Linq 查询的样子,但我知道它不正确。
林克:

var query = (from ta in ef.TableA
             where (from tb in ef.TableB
                    from tc in ef.TableC
                        .Where(tc => tc.ID == tb.fkC)
                    select new { NewNames = tb.StringField ?? SqlFunctions.StringConvert((double)tc.IntField) + SqlFunctions.StringConvert((double)tb.IntField2)}
                    ).Contains(ta.Filename)
             select ta.Filename
            ).Distinct().OrderBy(ta => ta.Filename).ToList();

由于子查询中创建的匿名类型,它抱怨Contains。这样做的正确方法是什么?

【问题讨论】:

  • LIKE怎么样?

标签: c# sql-server entity-framework linq


【解决方案1】:

你可以试试Any扩展方法:

var query = (from ta in ef.TableA
             where (from tb in ef.TableB
                    from tc in ef.TableC
                        .Where(tc => tc.ID == tb.fkC)
                    select new { NewNames = tb.StringField ?? SqlFunctions.StringConvert((double)tc.IntField) + SqlFunctions.StringConvert((double)tb.IntField2)}
                    ).Any(e.NewNames==ta.Filename)
             select ta.Filename
            ).Distinct().OrderBy(ta => ta.Filename).ToList();

或者您可以仅使用连接操作后获得的字符串来投影您的内部查询:

var query = (from ta in ef.TableA
             where (from tb in ef.TableB
                    from tc in ef.TableC
                        .Where(tc => tc.ID == tb.fkC)
                    select  (tb.StringField ?? SqlFunctions.StringConvert((double)tc.IntField) + SqlFunctions.StringConvert((double)tb.IntField2))
                    ).Contains(ta.Filename)
             select ta.Filename
            ).Distinct().OrderBy(ta => ta.Filename).ToList();

更新

我认为以下内容可以稍微改善您的查询:

var query = (from ta in ef.TableA
             where (from tb in ef.TableB
                    join tc in ef.TableC on tb.fkC equals tc.Id
                    where (tb.StringField ?? SqlFunctions.StringConvert((double)tc.IntField) + SqlFunctions.StringConvert((double)tb.IntField2))==ta.Filename
                    select tb).Any()
             select ta.Filename
            ).Distinct().OrderBy(ta => ta.Filename).ToList();

【讨论】:

  • 我仍然收到Any 的错误,但第二种方法似乎可行。但是,我收到超时错误,因为表很大并且它没有创建有效的查询。它最终执行了一个子查询,从 TableA 中选择所有内容,其中有很多记录。即使我翻转查询并从 TableB 开始(B 连接 C 连接 A)并仅连接 StringField = Filename(忽略可能的 NULL 情况),它仍然会这样做。
  • @wham12,我添加了一个新查询以提高效率。让我知道它是否有效。
  • 遗憾的是,它仍然将 TableA 的完整选择作为子查询。我想我只需要将我的 SQL 查询保存为存储过程并通过 EF 调用它。
  • 是的,我认为这是个好主意,有了SP你也可以避免使用SqlFunctions,这也会影响性能。
猜你喜欢
  • 2011-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多