首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对多个值更快地等效Server子句

对多个值更快地等效Server子句
EN

Stack Overflow用户
提问于 2015-10-23 13:31:32
回答 3查看 787关注 0票数 2

我使用的是OrmLite .NET和SQLServer12.0。我希望选择实体,其中某个整数列(不是主键)具有多个值中的一个,这是我在数组中拥有的。像这样的OrmLite表达式:

代码语言:javascript
运行
复制
q => query.Where(r => myIntegers.Contains(r.TheColumn))

被翻译成

代码语言:javascript
运行
复制
WHERE "TheColumn" IN (1, 2, 3, ...) -- my integers

这对100很好,但对1000来说是超时的。如何通过更大的列表实现同样的效果?我可以以某种方式将数组传递给Server或表参数吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-10-23 14:31:27

类似于@JoeTaras的注释,您可以将可接受的值放入子查询中,类似于;

代码语言:javascript
运行
复制
SELECT TheColumn from TheTable T
INNER JOIN (SELECT * from (VALUES(1),(2),(3),(4)) as V1(value)) V
ON T.TheColumn = V.value
票数 2
EN

Stack Overflow用户

发布于 2015-10-23 17:57:22

在OrmLite中,您可以构建所需的原始SQL查询(例如,从@Sam应答)并将其传递给db.Select方法:

代码语言:javascript
运行
复制
string joinedIds = string.Join("),(", new List<int> {1, 2, 9});

string command =
    $"SELECT * from Employee AS E INNER JOIN (SELECT * from (VALUES( {joinedIds} )) as TV(value)) V ON E.Id = V.value";

List<Employee> employers = db.Select<Employee>(command);
票数 1
EN

Stack Overflow用户

发布于 2015-11-17 15:36:18

最后,我为此使用了一个临时表,即:

代码语言:javascript
运行
复制
CREATE TABLE #ParamTempTable (Id BIGINT NOT NULL PRIMARY KEY);

INSERT INTO #ParamTempTable (Id) VALUES ((1), (2), (3));

SELECT *
FROM MyTable
WHERE Id IN (SELECT * FROM #ParamTempTable);

DROP TABLE #ParamTempTable;

只有当我有>1000个值时,我才会这样做,否则我只使用SQL IN (1, 2, 3)

要在OrmLite上实现这一点,我必须对SqlServerExpression<T>进行子类化,并重写VisitStaticArrayMethodCallVisitEnumerableMethodCall,以更改其处理Contains表达式的方式。这个类分别存储创建和删除临时表的命令,我必须对每个命令分别运行一个SqlCommand。(不幸的是,CREATE TABLE不适用于SqlCommand.ExecuteReader。)因此,这最终是相当复杂的,但它确实有效,并且对调用者来说是透明的。另一个好处是,我可以消除重复的参数,例如,对于o => ids.Contains(o.FromId) || ids.Contains(o.ToId),列表ids只发送一次给server。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33303620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档