【问题标题】:How do I write a Linq2Sql query that constrains rows with a collection of composite keys or tuples?如何编写一个 Linq2Sql 查询,用一组复合键或元组约束行?
【发布时间】:2014-12-02 03:57:11
【问题描述】:

我想编写一个 Linq 查询(SQL 后端),它通过来自多个列的值的集合来限制行。为了说明,如果我预先知道所有值,那么一个简单的 SQL 查询可能看起来像这样:

SELECT *
FROM myTable
WHERE (col1 = val1 AND col2 = val2 AND col2 = val3)
OR (col1 = val4 AND col2 = val5 AND col2 = val5)
OR (col1 = val6 AND col2 = val7 AND col2 = val8)
-- etc...

如果我在 SQL 中编写此代码,我会考虑对临时表、表值参数或类似构造使用连接。我将如何使用 Linq2Sql 完成此任务?我的值不存储在另一个表中,是根据代码和用户输入计算得出的,并且通常事先不知道——我将它们作为元组的集合接收。

我知道如果不先将整个表加载到内存中,我就无法加入内存中集合,并且在这些情况下仅限于使用Contains,从而导致WHERE ... IN 子句。是否可以将这种技术用于复合键和元组?

或者,我可以手动构建 WHERE 子句的表达式树,模拟上面示例中的 WHERE ... OR 子句。有没有更好的办法?我怀疑当子句中有数百条OR语句时,这样的SQL语句效率不会很高。

【问题讨论】:

    标签: sql sql-server linq expression-trees composite-key


    【解决方案1】:

    这个怎么样:

    var list = from mT in context.MyTables
               where (mT.col1 == val1 && mT.col2 == val2 && mT.col3 == val3)
               || (mT.col4 == val4 && mT.col5 == val5 && mT.col6 == val6)
               // etc etc
               select mT;
    

    ...其中 val1..val6 等是局部变量。这是“naïve”SQL 查询的非常直接的副本。

    【讨论】:

    • 感谢您的反馈!抱歉,我的问题并不清楚(我会编辑)——我真的不知道所有的值,因为它们作为集合传递给函数。
    • 你的意思是你在编译时得到了一个大小未知的 List 之类的东西?并且您需要将列表的第 x 个匹配到 colX?
    • 是的,假设集合的类型为List<Tuple<int, int, int>>。现在我需要为列表中的每个元素创建一个谓词,如下所示:where (mt.Col1 == list[0].Item1 && mt.Col2 == list[0].Item2 && mt.Col3 == list[0].Item3) || ( /* repeat for list[i] */ ...) 我可以创建一个循环并构建一个表达式树来执行此操作,但我很好奇是否有更简单的方法。
    • 我可以想象可能有另一种方式,但我实际上看不到它。如果有办法,我认为这将是非常复杂的代码,难以理解或维护,因此不是很理想。如果你能正常工作,我会使用表达式树。
    猜你喜欢
    • 2015-07-13
    • 1970-01-01
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多