Reputation: 1873
I'm trying to use Linq to SQL to search a text column for multiple matching words, but the query is not doing what I expect.
Here is my sample code:
string[] nameSearch = new string[2];
nameSearch[0] = "John";
nameSearch[1] = "Doe";
var customers = context.Customers.AsQueryable();
foreach (string name in nameSearch)
{
customers = customers.Where(r => r.CustName.Contains(name));
}
Data.Customer[] results = customers.ToArray();
The query that runs is:
SELECT [t0].[CustName]
FROM [dbo].[Customer] AS [t0]
WHERE ([t0].[CustName] LIKE @p0) AND ([t0].[CustName] LIKE @p1)
-- @p0: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [%Doe%]
-- @p1: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [%Doe%]
How do I fix this query? (It's suppose to be searching for John and Doe, not Doe and Doe.)
Upvotes: 1
Views: 3182
Reputation: 1065
string[] nameSearch = new string[2];
nameSearch[0] = "John";
nameSearch[1] = "Doe";
var result = customers.Where(r => nameSearch.Contains(r.CustName));
Upvotes: 1
Reputation: 262919
Your lambda expression is only evaluated when the query runs, i.e. during the call to ToArray()
. By then, name
is bound to the last item in your array.
You can use a local variable in your foreach
loop in order to avoid referencing the outer name
variable in your lambda expression:
var customers = context.Customers.AsQueryable();
for (string name in nameSearch) {
string curName = name;
customers = customers.Where(r => r.CustName.Contains(curName));
}
Data.Customer[] results = customers.ToArray();
Upvotes: 4
Reputation: 1972
No the above is wrong, it will overwrite customers every time !
customers = customers.Where(r => r.CustName.Contains("John") && r.CustName.Contains("Doe"));
Upvotes: 0
Reputation: 185842
foreach (string name in nameSearch)
{
string name_ = name;
customers = customers.Where(r => r.CustName.Contains(name_));
}
The lambda function r => r.CustName.Contains(name)
captures the name
variable. This same variable is in scope for both iterations. Using a block-scope temporary breaks this link, so that each invocation of the lambda function picks up a different variable with a distinct value.
Upvotes: 2