我很好奇探索使用Join
語法生成的sql而不是Contains
。下面是我的測試代碼:
IQueryable<Product> queryable = Uow.ProductRepository.All;
List<int> inMemKeys = new int[] { 2134, 1324543, 5675, 32451, 45735 }.ToList();
string sql1 = queryable.Where(p => inMemKeys.Contains(p.ID)).ToString();
string sql2 = queryable.Join(inMemKeys, t => t.ID, pk => pk, (t, pk) => t).ToString();
這是使用生成的SQL包含:(SQL1)
SELECT
[extent1].[id] AS [id],...etc
FROM [dbo].[products] AS [extent1]
WHERE ([extent1].[id] IN (2134, 1324543, 5675, 32451, 45735))
這是生成的SQL使用加入:
SELECT
[extent1].[id] AS [id],...etc
FROM [dbo].[products] AS [extent1]
INNER JOIN (SELECT
[unionall3].[c1] AS [c1]
FROM (SELECT
[unionall2].[c1] AS [c1]
FROM (SELECT
[unionall1].[c1] AS [c1]
FROM (SELECT
2134 AS [c1]
FROM (SELECT
1 AS x) AS [singlerowtable1] UNION ALL SELECT
1324543 AS [c1]
FROM (SELECT
1 AS x) AS [singlerowtable2]) AS [unionall1] UNION ALL SELECT
5675 AS [c1]
FROM (SELECT
1 AS x) AS [singlerowtable3]) AS [unionall2] UNION ALL SELECT
32451 AS [c1]
FROM (SELECT
1 AS x) AS [singlerowtable4]) AS [unionall3] UNION ALL SELECT
45735 AS [c1]
FROM (SELECT
1 AS x) AS [singlerowtable5]) AS [unionall4]
ON [extent1].[id] = [unionall4].[c1]
所以SQL使用union all創建一個大的select語句來創建臨時表的等價物,然後它加入到該表中。 sql比較冗長,但它可能很有效 - 恐怕我沒有資格說。
雖然它沒有回答標題中列出的問題,但確實顯示了避免巨人IN
的方法。好吧....現在這是一個巨大的UNION ALL
....反正...我希望這個貢獻對一些有用
你可以使用一個真正的表,其中有一個'userid'的列 – qujck
你意思是ProductID?最後我已經提到過這種可能性。 – wezten
如果您在過濾表(TempTable)中包含用戶標識或其他區分字段,那麼您將不會遇到併發用戶的問題。 – qujck