I have EF DataContext and would like to get data from SQL without getting full table from DB:
List<(int width, int height)> dimensions = new List<(int width, int height)>();
var res = context.DimensionData.Where(d =>
dimensions.Any(dim =>
dim.width == d.Width && dim.height == d.Height))
.ToList();
Using SQL Profiler I can see it will get full table and do slow in memory search.
How can I write Query so processing is done in DB?
I assume answering problem with SQL code and going back to Linq could give an answer how to do it. It seems a temp table needs to be generated for inner join and I am not sure how or if Linq is capable of this.
UPDATE 1: For now I've manage to find a package that does in memory collections join in DB: https://www.nuget.org/packages/EntityFrameworkCore.MemoryJoin
Unfortunately project is still on .Net Core 2.2 and cant upgrade to .Net Core 3.x because have breaking changes from base packages I need to use.
UPDATE 2:
0.5.7 version of MemoryJoin package worked for me as @Ivan Stoev suggested
SELECT [d].[Id], [d].[Width], [d].[Height]
FROM [DimensionData] AS [d]
INNER JOIN (
SELECT [x].[int1] AS [Width], [x].[int2] AS [Height]
FROM (
SELECT * FROM (VALUES (1, 55, 66), (2, 88, 99)) AS __gen_query_data__ (id, int1, int2)
) AS [x]
) AS [t] ON ([d].[Width] = [t].[Width]) AND ([d].[Height] = [t].[Height])
I don't think LINQ can pass a compound condition like that to SQL, but you may be able to narrow the rows returned by SQL with several simpler conditions.
Try:
The first Where should translate into SQL as something like:
(only much harder to read in the generated SQL)
The second .Where() will operate on the initial retrieved results to filter out the crossover cases like (width1,height2),(width3,height1).