Issue With LINQ and Reference List

c#, linq, linq-to-sql

Solution

Your first query expression uses `k1`. It uses the variable `kl`, and that's what's captured. When you change the value of `k1`, that's effectively changing the meaning of the query. If you don't want the meaning of the query to change, don't change the captured variables! Just use `k2` in your second filter:

var q = (from web in DataContext.Webs select web);
List<int?> k1 = new List<int?>() { 1, 2 };
List<int?> k2=new List<int?>() { 16, 17 };
q = q.Where(web => DataContext.WebTechMaps
                              .Any(t => t.WebsiteId == web.WebsiteId && 
                                        k1.Contains(t.TechId)));
System.Diagnostics.Debug.WriteLine(q.Count());
q = q.Where(web => DataContext.WebTechMaps
                              .Any(t => t.WebsiteId == web.WebsiteId &&
                                   k2.Contains(t.TechId)));
System.Diagnostics.Debug.WriteLine(q.Count());

Problem

I Have following code with LINQ ``` var q = (from web in DataContext.Webs select web); List<int?> k1 = new List<int?>() { 1, 2 }; List<int?> k2=new List<int?>() { 16, 17 }; q = q.Where(web => DataContext.WebTechMaps.Any(t => t.WebsiteId == web.WebsiteId && k1.Contains(t.TechId))); System.Diagnostics.Debug.WriteLine(q.Count()); k1 = k2; q = q.Where(web => DataContext.WebTechMaps.Any(t => t.WebsiteId == web.WebsiteId && k1.Contains(t.TechId))); System.Diagnostics.Debug.WriteLine(q.Count()); ``` Here Is what query it generates. First Execution of count. ``` SELECT COUNT(*) AS [value] FROM [dbo].[Web] AS [t0] WHERE EXISTS( SELECT NULL AS [EMPTY] FROM [dbo].[WebTechMap] AS [t1] WHERE ([t1].[WebsiteId] = ([t0].[WebsiteId])) AND ([t1].[TechId] IN (@p0, @p1)) ) -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [2] ``` Second Execution of count function ``` SELECT COUNT(*) AS [value] FROM [dbo].[Web] AS [t0] WHERE (EXISTS( SELECT NULL AS [EMPTY] FROM [dbo].[WebTechMap] AS [t1] WHERE ([t1].[WebsiteId] = ([t0].[WebsiteId])) AND ([t1].[TechId] IN (@p0, @p1)) )) AND (EXISTS( SELECT NULL AS [EMPTY] FROM [dbo].[WebTechMap] AS [t2] WHERE ([t2].[WebsiteId] = ([t0].[WebsiteId])) AND ([t2].[TechId] IN (@p2, @p3)) )) -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [16] -- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [17] -- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [16] -- @p3: Input Int (Size = -1; Prec = 0; Scale = 0) [17] ``` Please Take a look at the parameters passed to query. Seems it uses the new referenced object for both Expressions. Somehow @p0 and @p1 change their old values. I understand that issue is in Linq it uses new referenced object. ``` -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [2] -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [16] -- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [17] -- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [16] -- @p3: Input Int (Size = -1; Prec = 0; Scale = 0) [17] ``` Can someone explain how to use same name of List object but keep the query using correct List's Desired output is ``` -- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] -- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [2] -- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [16] -- @p3: Input Int (Size = -1; Prec = 0; Scale = 0) [17] ``` Thanks in Advance

Original source